Оптимизация запросов в 1С
1. Получение значения поля составного типа через точку
Получение значения поля составного типа называется разыменованием ссылочного поля.
При обращении к полям через точку система неявно создает дополнительный запрос, а потом соединяет полученные таблицы.
Например, запрос следующего вида:
ВЫБРАТЬ
ТоварыНаСкладах.Склад.Наименование
ИЗ
РегистрНакопления.ТоварыНаСкладах КАК ТоварыНаСкладах
фактически выглядит так:
ВЫБРАТЬ
Склады.Наименование
ИЗ
РегистрНакопления.ТоварыНаСкладах КАК ТоварыНаСкладах
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Склады КАК Склады
ПО ТоварыНаСкладах.Склад = Склады.Ссылка
Но есть один важный момент. При разыменовании ссылочного поля система создает дополнительные запросы для всех объектов, которые входят в тип этого поля.
Например, если нам нужно получить дату документа регистратора:
ВЫБРАТЬ
ТоварыНаСкладах.Регистратор.Дата
ИЗ
РегистрНакопления.ТоварыНаСкладах КАК ТоварыНаСкладах
то запрос будет неоптимальным и будет выполняться очень медленно, т.к. система создаст запросы на выборку данных для всех возможных регистраторов этого регистра, а их количество может исчисляться сотнями.
В случае, если заранее известен тип регистратора, то обязательно нужно ограничиться только им при помощи конструкции ВЫРАЗИТЬ(<Выражение> КАК <Тип>):
ВЫБРАТЬ
ВЫРАЗИТЬ(ТоварыНаСкладах.Регистратор КАК Документ.ПоступлениеТоваровУслуг).Дата КАК ДатаДокумента
ИЗ
РегистрНакопления.ТоварыНаСкладах КАК ТоварыНаСкладах
Аналогичный запрос для двух регистраторов:
ВЫБРАТЬ
ВЫБОР
КОГДА ТоварыНаСкладах.Регистратор ССЫЛКА Документ.ПоступлениеТоваровУслуг
ТОГДА ВЫРАЗИТЬ(ТоварыНаСкладах.Регистратор КАК Документ.ПоступлениеТоваровУслуг).Дата
КОГДА ТоварыНаСкладах.Регистратор ССЫЛКА Документ.РеализацияТоваровУслуг
ТОГДА ВЫРАЗИТЬ(ТоварыНаСкладах.Регистратор КАК Документ.РеализацияТоваровУслуг).Дата
КОНЕЦ КАК ДатаДокумента
ИЗ
РегистрНакопления.ТоварыНаСкладах КАК ТоварыНаСкладах
2. Отбор в виртуальной таблице
Когда необходимо сделать отбор в виртуальной таблице хочется написать следующий запрос:
ВЫБРАТЬ
ТоварыНаСкладахОстатки.КоличествоОстаток
ИЗ
РегистрНакопления.ТоварыНаСкладах.Остатки(, ) КАК ТоварыНаСкладахОстатки
ГДЕ
ТоварыНаСкладахОстатки.Склад = &Склад
Такой запрос не является оптимальным. Дело в том, что в этом случае система выберет сначала все данные, и лишь потом применит к ним отбор. Правильным будет использование условий непосредственно в параметрах виртуальной таблицы:
ВЫБРАТЬ
ТоварыНаСкладахОстатки.КоличествоОстаток
ИЗ
РегистрНакопления.ТоварыНаСкладах.Остатки(, Склад = &Склад) КАК ТоварыНаСкладахОстатки
3. Текстовое представление объекта ссылочного типа
При получении в запросе объекта ссылочного типа:
ВЫБРАТЬ
ТоварыНаСкладах.Склад
ИЗ
РегистрНакопления.ТоварыНаСкладах КАК ТоварыНаСкладах
или при разыменовании:
ВЫБРАТЬ
ТоварыНаСкладах.Склад.Наименование
ИЗ
РегистрНакопления.ТоварыНаСкладах КАК ТоварыНаСкладах
система всегда создает дополнительный подзапрос.
В случае, когда необходимо вывести лишь текстовое представление объекта нужно использовать функцию ПРЕДСТАВЛЕНИЕ(<Выражение>):
ВЫБРАТЬ
ПРЕДСТАВЛЕНИЕ(ТоварыНаСкладах.Склад)
ИЗ
РегистрНакопления.ТоварыНаСкладах КАК ТоварыНаСкладах
Запрос в этом случае будет оптимальным, т.к. не будет создаваться дополнительная таблица.
Как найти неоптимальные запросы?
- Несколько раз выполняем запрос, чтобы заполнить кэши и пр.
- Ставим точку останова на моменте выполнения запроса.
- Открываем SQL Server Profiler.
- Запускаем в профайлере трассировку.
- Выполняем запрос.
- Смотрим план выполнения запроса.
- Оцениваем показатели Duration (время выполнения запроса) и Reads (количество логических чтений). Последний показатель не должен измеряться тысяцами.
Добавить комментарий