Оптимизация запросов в 1С

01 Oct
Published by Nicholas

1. Получение значения поля составного типа через точку

Получение значения поля составного типа называется разыменованием ссылочного поля.

При обращении к полям через точку система неявно создает дополнительный запрос, а потом соединяет полученные таблицы.

Например, запрос следующего вида:

ВЫБРАТЬ
    ТоварыНаСкладах.Склад.Наименование
ИЗ
   
РегистрНакопления.ТоварыНаСкладах КАК ТоварыНаСкладах

фактически выглядит так:

ВЫБРАТЬ
    Склады.Наименование
ИЗ
   
РегистрНакопления.ТоварыНаСкладах КАК ТоварыНаСкладах
        ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Склады КАК Склады
        ПО ТоварыНаСкладах.Склад = Склады.Ссылка

Но есть один важный момент. При разыменовании ссылочного поля система создает дополнительные запросы для всех объектов, которые входят в тип этого поля.

Например, если нам нужно получить дату документа регистратора:

ВЫБРАТЬ
    ТоварыНаСкладах.Регистратор.Дата
ИЗ
   
РегистрНакопления.ТоварыНаСкладах КАК ТоварыНаСкладах

то запрос будет неоптимальным и будет выполняться очень медленно, т.к. система создаст запросы на выборку данных для всех возможных регистраторов этого регистра, а их количество может исчисляться сотнями.

В случае, если заранее известен тип регистратора, то обязательно нужно ограничиться только им при помощи конструкции ВЫРАЗИТЬ(<Выражение> КАК <Тип>):

ВЫБРАТЬ
    ВЫРАЗИТЬ(ТоварыНаСкладах.Регистратор КАК Документ.ПоступлениеТоваровУслуг).Дата КАК ДатаДокумента
ИЗ
   
РегистрНакопления.ТоварыНаСкладах КАК ТоварыНаСкладах

Аналогичный запрос для двух регистраторов:

ВЫБРАТЬ
    ВЫБОР
        КОГДА ТоварыНаСкладах.Регистратор ССЫЛКА Документ.ПоступлениеТоваровУслуг
            ТОГДА ВЫРАЗИТЬ(ТоварыНаСкладах.Регистратор КАК Документ.ПоступлениеТоваровУслуг).Дата
        КОГДА ТоварыНаСкладах.Регистратор ССЫЛКА Документ.РеализацияТоваровУслуг
            ТОГДА ВЫРАЗИТЬ(ТоварыНаСкладах.Регистратор КАК Документ.РеализацияТоваровУслуг).Дата
    КОНЕЦ КАК ДатаДокумента
ИЗ
   
РегистрНакопления.ТоварыНаСкладах КАК ТоварыНаСкладах


2. Отбор в виртуальной таблице

Когда необходимо сделать отбор в виртуальной таблице хочется написать следующий запрос:

ВЫБРАТЬ
    ТоварыНаСкладахОстатки.КоличествоОстаток
ИЗ
   
РегистрНакопления.ТоварыНаСкладах.Остатки(, ) КАК ТоварыНаСкладахОстатки
ГДЕ
    ТоварыНаСкладахОстатки.Склад = &Склад

Такой запрос не является оптимальным. Дело в том, что в этом случае система выберет сначала все данные, и лишь потом применит к ним отбор. Правильным будет использование условий непосредственно в параметрах виртуальной таблицы:

ВЫБРАТЬ
    ТоварыНаСкладахОстатки.КоличествоОстаток
ИЗ
   
РегистрНакопления.ТоварыНаСкладах.Остатки(, Склад = &Склад) КАК ТоварыНаСкладахОстатки


3. Текстовое представление объекта ссылочного типа

При получении в запросе объекта ссылочного типа:

ВЫБРАТЬ
    ТоварыНаСкладах.Склад
ИЗ
   
РегистрНакопления.ТоварыНаСкладах КАК ТоварыНаСкладах

или при разыменовании:

ВЫБРАТЬ
    ТоварыНаСкладах.Склад.Наименование
ИЗ
   
РегистрНакопления.ТоварыНаСкладах КАК ТоварыНаСкладах

система всегда создает дополнительный подзапрос.

В случае, когда необходимо вывести лишь текстовое представление объекта нужно использовать функцию ПРЕДСТАВЛЕНИЕ(<Выражение>):

ВЫБРАТЬ
    ПРЕДСТАВЛЕНИЕ(ТоварыНаСкладах.Склад)
ИЗ
   
РегистрНакопления.ТоварыНаСкладах КАК ТоварыНаСкладах

Запрос в этом случае будет оптимальным, т.к. не будет создаваться дополнительная таблица.


Как найти неоптимальные запросы?

  1. Несколько раз выполняем запрос, чтобы заполнить кэши и пр.
  2. Ставим точку останова на моменте выполнения запроса.
  3. Открываем SQL Server Profiler.
  4. Запускаем в профайлере трассировку.
  5. Выполняем запрос.
  6. Смотрим план выполнения запроса.
  7. Оцениваем показатели Duration (время выполнения запроса) и Reads (количество логических чтений). Последний показатель не должен измеряться тысяцами.

Tags 

СКД

Добавить комментарий

Plain text

  • HTML-теги не обрабатываются и показываются как обычный текст
  • Строки и абзацы переносятся автоматически.
CAPTCHA
Вы человек или автоматическая спам-рассылка?
Target Image