Ускорение запроса или операции

Не всегда бывает необходимость оптимизировать всю информационную систему а только конкретное место. Особенно актуален такой вариант может  быть когда программист компании уже какое время потратил на решение вопроса.

Рассмотрим пример ускорения запросов из практики.
1. Дано: долгое открытие формы документов «Установка цен номенклатуры», иногда оператор вынужден по нескольку минут ждать открытия формы.
Сервисом QueryTJ или другими способами фиксируем долгое выполнение запроса загрузки табличной части товаров:
Запрос = Новый Запрос(«
                  |ВЫБРАТЬ
                  |                 ВременнаяТаблицаТовары.Индекс                         КАК Индекс,
                  |                 ВременнаяТаблицаТовары.Номенклатура                   КАК Номенклатура,
                  |                 ВременнаяТаблицаТовары.Характеристика                 КАК Характеристика,
                  |                 ВременнаяТаблицаТовары.ВидЦены                        КАК ВидЦены,
                  |                 ВременнаяТаблицаТовары.Цена                           КАК Цена,
                  |                 ВременнаяТаблицаТовары.Упаковка                       КАК Упаковка,
                  |                 ВременнаяТаблицаТовары.ЦенаИзмененаВручную            КАК ЦенаИзмененаВручную
                  |ПОМЕСТИТЬ
                  |                 ВременнаяТаблицаТовары
                  |ИЗ
                  |                 &Товары КАК ВременнаяТаблицаТовары
                  |ИНДЕКСИРОВАТЬ ПО Номенклатура, Характеристика, ВидЦены
                  |;
                  |ВЫБРАТЬ
                  |                 ВременнаяТаблицаТовары.Индекс                         КАК Индекс,
                  |                 ВременнаяТаблицаТовары.Номенклатура                   КАК Номенклатура,
                  |                 ВременнаяТаблицаТовары.Номенклатура.Артикул           КАК Артикул,
                  |                 ВременнаяТаблицаТовары.Характеристика                 КАК Характеристика,
                  |                 ВременнаяТаблицаТовары.Номенклатура.ЕдиницаИзмерения  КАК ЕдиницаИзмерения,
                  |                 ВременнаяТаблицаТовары.Номенклатура.ЦеноваяГруппа     КАК ЦеноваяГруппа,
                  |
                  |                 ВЫБОР
                  |                                   КОГДА ВременнаяТаблицаТовары.Номенклатура.ИспользованиеХарактеристик = ЗНАЧЕНИЕ(Перечисление.ВариантыИспользованияХарактеристикНоменклатуры.ОбщиеДляВидаНоменклатуры) ТОГДА Истина
                  |                                   КОГДА ВременнаяТаблицаТовары.Номенклатура.ИспользованиеХарактеристик = ЗНАЧЕНИЕ(Перечисление.ВариантыИспользованияХарактеристикНоменклатуры.ИндивидуальныеДляНоменклатуры) ТОГДА Истина
                  |                 ИНАЧЕ Ложь КОНЕЦ КАК ХарактеристикиИспользуются,
                  |
                  |                 ВременнаяТаблицаТовары.ВидЦены                        КАК ВидЦены,
                  |                 ВременнаяТаблицаТовары.Цена                           КАК Цена,
                  |                 ВременнаяТаблицаТовары.ЦенаИзмененаВручную            КАК ЦенаИзмененаВручную,
                  |
                  |                 ВЫБОР КОГДА ЦеныНоменклатуры.Упаковка = ВременнаяТаблицаТовары.Упаковка ТОГДА
                  |                                   ЦеныНоменклатуры.Цена
                  |                 ИНАЧЕ
                  |                                   ЦеныНоменклатуры.Цена/ЕСТЬNULL(ЦеныНоменклатуры.Упаковка.Коэффициент,1)*ЕСТЬNULL(ВременнаяТаблицаТовары.Упаковка.Коэффициент,1)
                  |                 КОНЕЦ КАК ДействующаяЦена,
                  |
                  |                 ВЫРАЗИТЬ(ВЫБОР КОГДА ЦеныНоменклатуры.Цена <> 0 Тогда 100*(ВременнаяТаблицаТовары.Цена — ВЫБОР КОГДА ЦеныНоменклатуры.Упаковка = ВременнаяТаблицаТовары.Упаковка ТОГДА
                  |                                   ЦеныНоменклатуры.Цена
                  |                 ИНАЧЕ
                  |                                   ЦеныНоменклатуры.Цена/ЕСТЬNULL(ЦеныНоменклатуры.Упаковка.Коэффициент,1)*ЕСТЬNULL(ВременнаяТаблицаТовары.Упаковка.Коэффициент,1)
                  |                 КОНЕЦ)/
                  |
                  |                 ВЫБОР КОГДА ЦеныНоменклатуры.Упаковка = ВременнаяТаблицаТовары.Упаковка ТОГДА
                  |                                   ЦеныНоменклатуры.Цена
                  |                 ИНАЧЕ
                  |                                   ЦеныНоменклатуры.Цена/ЕСТЬNULL(ЦеныНоменклатуры.Упаковка.Коэффициент,1)*ЕСТЬNULL(ВременнаяТаблицаТовары.Упаковка.Коэффициент,1)
                  |                 КОНЕЦ ИНАЧЕ 0.00 КОНЕЦ КАК Число(10,2)) КАК Процент,
                  |
                  |                 ВременнаяТаблицаТовары.Упаковка                       КАК Упаковка
                  |ИЗ
                  |                 ВременнаяТаблицаТовары КАК ВременнаяТаблицаТовары
                  |
                  |                 ЛЕВОЕ СОЕДИНЕНИЕ
                  |                                   РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&Дата, (Номенклатура, Характеристика) В (Выбрать Номенклатура, Характеристика Из ВременнаяТаблицаТовары)) КАК ЦеныНоменклатуры
                  |                                                     ПО ЦеныНоменклатуры.Номенклатура   = ВременнаяТаблицаТовары.Номенклатура
                  |                                                     И ЦеныНоменклатуры.Характеристика = ВременнаяТаблицаТовары.Характеристика
                  |                                                     И ЦеныНоменклатуры.ВидЦены        = ВременнаяТаблицаТовары.ВидЦены
                  |
                  |УПОРЯДОЧИТЬ ПО
                  |                 Индекс
                  |
                  |ИТОГИ
                  |                 МИНИМУМ(ЕдиницаИзмерения) КАК ЕдиницаИзмерения
                  |ПО
                  |                 Номенклатура,
                  |                 Характеристика
                  |»);
Мы обозначаем стоимость решения подобных задач и берем оплату только в случаи достижения результата. В данном случаи нужно было ускорить минимум на 5 секунд.
В результате анализа выяснили, что в

 запросе использовалось соединение с виртуальной таблицей ЦеныНоменклатуры.
СрезПоследних, по данному соединению происходил неээфективный отбор, не попадал в индекс и получался плохой план запросов.
В изменённом запросе данная виртуальная таблица была «воссоздана» с помощью запроса к таблице ЦеныНоменклатуры в упрощенном виде. Был проигнорирован признак активности, и также на начальном этапе был применен только отбор по номенклатуре, что позволило попасть в существующий индекс. Для данного конкретного случая это дало хороший выигрыш в производительности (на тестовом документе с 7100 строк, вместо 19.8 секунд запрос стал выполняться 13 секунд, а несколькоминутные открытия документов более не фиксируются).
Запрос = Новый Запрос(«
                  |ВЫБРАТЬ
                  |                 УстановкаЦенНоменклатурыТовары.НомерСтроки КАК Индекс,
                  |                 УстановкаЦенНоменклатурыТовары.Номенклатура,
                  |                 УстановкаЦенНоменклатурыТовары.Характеристика,
                  |                 УстановкаЦенНоменклатурыТовары.Упаковка,
                  |                 УстановкаЦенНоменклатурыТовары.ВидЦены,
                  |                 УстановкаЦенНоменклатурыТовары.Цена,
                  |                 УстановкаЦенНоменклатурыТовары.ЦенаИзмененаВручную
                  |ПОМЕСТИТЬ ВременнаяТаблицаТовары
                  |ИЗ
                  |                 &Товары КАК УстановкаЦенНоменклатурыТовары
                  |ИНДЕКСИРОВАТЬ ПО Номенклатура, Характеристика, ВидЦены
                  |;
                  |
                  |////////////////////////////////////////////////////////////////////////////////
                  |ВЫБРАТЬ
                  |                 ЦеныНоменклатуры.Период,
                  |                 ЦеныНоменклатуры.Номенклатура,
                  |                 ЦеныНоменклатуры.ВидЦены,
                  |                 ЦеныНоменклатуры.Характеристика,
                  |                 ЦеныНоменклатуры.Цена,
                  |                 ЦеныНоменклатуры.Упаковка
                  |ПОМЕСТИТЬ времЦеныНоменклатуры
                  |ИЗ
                  |                 (ВЫБРАТЬ
                  |                                   МАКСИМУМ(ЦеныНоменклатуры.Период) КАК Период,
                  |                                   ЦеныНоменклатуры.Номенклатура КАК Номенклатура,
                  |                                   ЦеныНоменклатуры.ВидЦены КАК ВидЦены,
                  |                                   ЦеныНоменклатуры.Характеристика КАК Характеристика
                  |                 ИЗ
                  |                                   (ВЫБРАТЬ
                  |                                                     ЦеныНоменклатуры.Период КАК Период,
                  |                                                     ЦеныНоменклатуры.Номенклатура КАК Номенклатура,
                  |                                                     ЦеныНоменклатуры.ВидЦены КАК ВидЦены,
                  |                                                     ЦеныНоменклатуры.Характеристика КАК Характеристика
                  |                                   ИЗ
                  |                                                     РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры
                  |                                   ГДЕ
                  |                                                     ЦеныНоменклатуры.Период <= &Дата
                  |                                                     И ЦеныНоменклатуры.Номенклатура В
                  |                                                                                         (ВЫБРАТЬ
                  |                                                                                                           ВременнаяТаблицаТовары.Номенклатура
                  |                                                                                         ИЗ
                  |                                                                                                           ВременнаяТаблицаТовары)) КАК ЦеныНоменклатуры
                  |
                  |                 СГРУППИРОВАТЬ ПО
                  |                                   ЦеныНоменклатуры.Номенклатура,
                  |                                   ЦеныНоменклатуры.ВидЦены,
                  |                                   ЦеныНоменклатуры.Характеристика) КАК Вложенный
                  |                                   ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры
                  |                                   ПО Вложенный.Период = ЦеныНоменклатуры.Период
                  |                                                     И Вложенный.Номенклатура = ЦеныНоменклатуры.Номенклатура
                  |                                                     И Вложенный.ВидЦены = ЦеныНоменклатуры.ВидЦены
                  |                                                     И Вложенный.Характеристика = ЦеныНоменклатуры.Характеристика
                  |ИНДЕКСИРОВАТЬ ПО ЦеныНоменклатуры.Номенклатура, ЦеныНоменклатуры.Характеристика, ЦеныНоменклатуры.ВидЦены
                  |;
                  |
                  |////////////////////////////////////////////////////////////////////////////////
                  |ВЫБРАТЬ
                  |                 ВременнаяТаблицаТовары.Индекс КАК Индекс,
                  |                 ВременнаяТаблицаТовары.Номенклатура КАК Номенклатура,
                  |                 ВременнаяТаблицаТовары.Номенклатура.Артикул КАК Артикул,
                  |                 ВременнаяТаблицаТовары.Характеристика КАК Характеристика,
                  |                 ВременнаяТаблицаТовары.Номенклатура.ЕдиницаИзмерения КАК ЕдиницаИзмерения,
                  |                 ВременнаяТаблицаТовары.Номенклатура.ЦеноваяГруппа КАК ЦеноваяГруппа,
                  |                 ВЫБОР
                  |                                   КОГДА ВременнаяТаблицаТовары.Номенклатура.ИспользованиеХарактеристик = ЗНАЧЕНИЕ(Перечисление.ВариантыИспользованияХарактеристикНоменклатуры.ОбщиеДляВидаНоменклатуры)
                  |                                                     ТОГДА ИСТИНА
                  |                                   КОГДА ВременнаяТаблицаТовары.Номенклатура.ИспользованиеХарактеристик = ЗНАЧЕНИЕ(Перечисление.ВариантыИспользованияХарактеристикНоменклатуры.ИндивидуальныеДляНоменклатуры)
                  |                                                     ТОГДА ИСТИНА
                  |                                   ИНАЧЕ ЛОЖЬ
                  |                 КОНЕЦ КАК ХарактеристикиИспользуются,
                  |                 ВременнаяТаблицаТовары.ВидЦены КАК ВидЦены,
                  |                 ВременнаяТаблицаТовары.Цена КАК Цена,
                  |                 ВременнаяТаблицаТовары.ЦенаИзмененаВручную КАК ЦенаИзмененаВручную,
                  |                 ВЫБОР
                  |                                   КОГДА ЦеныНоменклатуры.Упаковка = ВременнаяТаблицаТовары.Упаковка
                  |                                                     ТОГДА ЦеныНоменклатуры.Цена
                  |                                   ИНАЧЕ ЦеныНоменклатуры.Цена / ЕСТЬNULL(ЦеныНоменклатуры.Упаковка.Коэффициент, 1) * ЕСТЬNULL(ВременнаяТаблицаТовары.Упаковка.Коэффициент, 1)
                  |                 КОНЕЦ КАК ДействующаяЦена,
                  |                 ВЫРАЗИТЬ(ВЫБОР
                  |                                                     КОГДА ЦеныНоменклатуры.Цена <> 0
                  |                                                                       ТОГДА 100 * (ВременнаяТаблицаТовары.Цена — ВЫБОР
                  |                                                                                                           КОГДА ЦеныНоменклатуры.Упаковка = ВременнаяТаблицаТовары.Упаковка
                  |                                                                                                                             ТОГДА ЦеныНоменклатуры.Цена
                  |                                                                                                           ИНАЧЕ ЦеныНоменклатуры.Цена / ЕСТЬNULL(ЦеныНоменклатуры.Упаковка.Коэффициент, 1) * ЕСТЬNULL(ВременнаяТаблицаТовары.Упаковка.Коэффициент, 1)
                  |                                                                                         КОНЕЦ) / ВЫБОР
                  |                                                                                                           КОГДА ЦеныНоменклатуры.Упаковка = ВременнаяТаблицаТовары.Упаковка
                  |                                                                                                                             ТОГДА ЦеныНоменклатуры.Цена
                  |                                                                                                           ИНАЧЕ ЦеныНоменклатуры.Цена / ЕСТЬNULL(ЦеныНоменклатуры.Упаковка.Коэффициент, 1) * ЕСТЬNULL(ВременнаяТаблицаТовары.Упаковка.Коэффициент, 1)
                  |                                                                                         КОНЕЦ
                  |                                                     ИНАЧЕ 0
                  |                                   КОНЕЦ КАК ЧИСЛО(10, 2)) КАК Процент,
                  |                 ВременнаяТаблицаТовары.Упаковка КАК Упаковка
                  |ИЗ
                  |                 ВременнаяТаблицаТовары КАК ВременнаяТаблицаТовары
                  |                                   ЛЕВОЕ СОЕДИНЕНИЕ времЦеныНоменклатуры КАК ЦеныНоменклатуры
                  |                                   ПО (ЦеныНоменклатуры.Номенклатура = ВременнаяТаблицаТовары.Номенклатура)
                  |                                                     И (ЦеныНоменклатуры.Характеристика = ВременнаяТаблицаТовары.Характеристика)
                  |                                                     И (ЦеныНоменклатуры.ВидЦены = ВременнаяТаблицаТовары.ВидЦены)
                  |
                  |УПОРЯДОЧИТЬ ПО
                  |                 Индекс
                  |ИТОГИ
                  |                 МИНИМУМ(ЕдиницаИзмерения)
                  |ПО
                  |                 Номенклатура,
                  |                 Характеристика
                  |»);

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

Пример типового договора можно скачать здесь