Книга: Настольная книга 1С:Эксперта по технологическим вопросам
Назад: Пояснение к правилу 4 (соответствие индексов и условий запроса)
Дальше: Пояснение к правилу 9 (не использовать соединения с подзапросами, а использовать временные таблицы)

Пояснение к правилу 8 (не использовать подзапросы в условиях)

В качестве иллюстрации приводится фрагмент статьи К. Рупасова «Типичные причины неоптимальной работы запросов и методы оптимизации», фрагмент приведен без изменений.

Не следует использовать подзапросы в условии соединения (и не только в условии соединения, но и вообще в условиях. – Примеч. авт.). Это может привести к значительному замедлению запроса и (в отдельных случаях) к его полной неработоспособности на некоторых СУБД. Пример запроса с использованием подзапроса в условии соединения:

Запрос.Текст = "ВЫБРАТЬ

| ОстаткиТоваров.Номенклатура КАК Номенклатура,

| Цены.Цена КАК ЦенаПрошлогоМесяца

|ИЗ

| РегистрНакопления.ТоварыНаСкладах.Остатки(...) КАК ОстаткиТоваров

| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.Цена КАК Цены

| ПО Цены.Номенклатура = ОстаткиТоваров.Номенклатура И

| Цены.Период В (

| ВЫБРАТЬ МАКСИМУМ(ЦеныПрошлогоМесяца.Период)

| ИЗ РегистрСведений.Цена КАК ЦеныПрошлогоМесяца

| ГДЕ ЦеныПрошлогоМесяца.Период

| И ЦеныПрошлогоМесяца.Номенклатура = ОстаткиТоваров.Номенклатура

| )

| ГДЕ ОстаткиТоваров.Склад = &Склад";

В данном случае подзапрос в условии соединения используется для получения как бы «среза последних» на конец предыдущего периода. Причем для каждой номенклатуры период может быть разным. Подобный запрос рекомендуется переписать с использованием временных таблиц. Например, это можно сделать следующим образом:

Запрос.Текст = "

// Максимальные даты установки цен в прошлом периоде для данных номенклатур

|ВЫБРАТЬ

| ОстаткиТоваров.Номенклатура КАК Номенклатура,

| МАКСИМУМ(Цены.Период) КАК Период

|ПОМЕСТИТЬ ДатыПоНоменклатурам

|ИЗ

| РегистрНакопления.ТоварыНаСкладах.Остатки(...) КАК ОстаткиТоваров

| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.Цена КАК Цены

| ПО Цены.Номенклатура = ОстаткиТоваров.Номенклатура И

| Цены.Период

| СГРУППИРОВАТЬ ПО ОстаткиТоваров.Номенклатура

| ГДЕ ОстаткиТоваров.Склад = &Склад;

// Выбрать данные по цене за найденный период

|ВЫБРАТЬ

| ДатыПоНоменклатурам.Номенклатура КАК Номенклатура,

| Цены.Цена КАК ЦенаПрошлогоМесяца

|ИЗ ДатыПоНоменклатурам

| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.Цена КАК Цены

| ПО Цены.Номенклатура = ОстаткиТоваров.Номенклатура И

| Цены.Период = ДатыПоНоменклатурам.Период

";

Назад: Пояснение к правилу 4 (соответствие индексов и условий запроса)
Дальше: Пояснение к правилу 9 (не использовать соединения с подзапросами, а использовать временные таблицы)