День добры! Ситуация в следующем.
Попался мне отчет написанный в СКД, который долго формировался. решил его оптимизировать. Начал с переписывания запроса. В результате получилась следующая оптимизация:
(проверял по стандартному "Замер производительности")
Мой запрос срабатывает : за 1 секунду
Старый запрос срабатывает: за 26 секунд
В запросе есть один параметр, при замере заполнял этот параметр вручную.
Вставляю свой запрос в СКД, проверяю время выполнения 5 секунд. Проверяю отчет с старым запрос (чьё время срабатывания 26 секунд) время выполнения те же 5 секунд.
Слышал, что если указан какой-то параметр в отборе (настройки пользователя), то если этот отбор заполнен, то СКД подставит проверку реквизита на самый "верх" запроса.
Это объясняет почему запрос который выполняется 26 секунд, в СКД выполняется за 5.
Но почему тогда мой запрос, выполняется в СКД те же 5 секунд?
(8) делайте план запроса и смотрите где не оптимально. Гилевы рекламируют свой сервис попробуй через него прогнать, но 5 секунд я думаю этого не стоят!
(16) Первые три временные таблицы избыточные. Дальше анализировать не стал, так как проблема у разработчика явно системная. Когда разработчик избавится от этой ошибки в запросе и запрос станет втрое меньше, можно будет анализировать дальше.
Объясню, в чем ошибка. Четвертый и пятый запрос гораздо легче собирается без первых трех. Более того, вы лишили оптимизатор возможности выбора. Со временем, без индексов на первых трех временных таблицах 4 и 5 подзапросы деградируют. Но и при наличии индексов первые три временные таблицы не нужны. В пятом подзапросе надо загонять отбор по документам в параметры виртуальной таблицы (соединение избыточно).
И вот эта избыточность, которую не может оптимизировать ни СКД, ни оптимизатор SQL, она так и сквозит в ваших запросах. Дальше шестого запроса не смотрю, слишком много букв.
(18)
Правильно ли я вас понял, что вы предлагаете сделать следующим образом? (Выкинул перечень что тянуть для визуального уменьшения)
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
СИТ_СтроительнаяСпецификацияЭлементыСтроительныхСмет.ЭлементСметы,
СИТ_СтроительнаяСпецификацияСтроительнаяСпецификация.СтроительнаяНоменклатура,
ПОМЕСТИТЬ втСС
ИЗ
Документ.СИТ_СтроительнаяСпецификация.СтроительнаяСпецификация КАК СИТ_СтроительнаяСпецификацияСтроительнаяСпецификация
ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.СИТ_СтроительнаяСпецификация.ЭлементыСтроительныхСмет КАК СИТ_СтроительнаяСпецификацияЭлементыСтроительныхСмет
ПО СИТ_СтроительнаяСпецификацияСтроительнаяСпецификация.КлючЗаписиЭлементСметы = СИТ_СтроительнаяСпецификацияЭлементыСтроительныхСмет.КлючЗаписиЭлементСметы
И СИТ_СтроительнаяСпецификацияСтроительнаяСпецификация.Ссылка = СИТ_СтроительнаяСпецификацияЭлементыСтроительныхСмет.Ссылка
ГДЕ
НЕ СИТ_СтроительнаяСпецификацияСтроительнаяСпецификация.Ссылка.ПометкаУдаления
ИНДЕКСИРОВАТЬ ПО
| ЭлементСтроительнойСпецификации
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
СИТ_ЗаказыПоСтроительнымСпецификациямВСЗСОбороты.Регистратор КАК Регистратор
ПОМЕСТИТЬ втЭлСЗС
ИЗ
втСС КАК втСС
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.СИТ_ЗаказыПоСтроительнымСпецификациямВСЗС.Обороты(, , Регистратор, ) КАК СИТ_ЗаказыПоСтроительнымСпецификациямВСЗСОбороты
ПО втСС.ЭлементСтроительнойСпецификации = СИТ_ЗаказыПоСтроительнымСпецификациямВСЗСОбороты.ЭлементСпецификации
ИНДЕКСИРОВАТЬ ПО
ЭлементСводноЗаказнойСпецификации,
Регистратор,
ЭлементСтроительнойСпецификации
;
Показать
Если нет, то не могли бы вы внести корректировки связанные с вашим предложением?
(22) Попробовал ваш вариант. Хотя ещё на сообщении (18) уже отнесся к нему скептически, но подумал мало ли я чего-то не знаю. Ваш вариант (замены 1-5 пакета в 2) (не всего кода) срабатывает за 4 секунды (после кэширования 3,9), мой, как вы выразились "с избыточными соединениями" за 0,06 секунды, (после кэширования за 0,02 секунды). Весь код при вашем варианте срабатывает за 26,39 секунды, мой за 1. Что как бы показывает, что ваш вариант не является оптимальным.
"Но я подозреваю, что и этот и следующий запрос оба являются ошибкой проектирования. " - там вся база ошибка проектирования. Базу спроектировали так успешно, что при работе 20 человек за 2 года, база имеет размер 100 гигабайт.
А это чужой запрос, решил его оптимизировать. Что в принципе получилось, Но СКД все портит =(
(24) Поймите, прямое указание к действию я могу дать, только если сам отлажу запрос. Я вам дал общее направление, у вас запрос перенасыщен. Скорее всего, по всему телу запроса. Попробуйте понять, что должно получиться в результате запроса, а потом построить его с нуля, а не оптимизировать эту портянку.
(24)СКД не портит, а как раз оптимизирует!
СКД в виртуальных таблицах остатков и оборотов вставляет свои параметры(если вы добавите в запросе таблицу, например ОстаткиТоваровНаСкладах и не добавите к ней ни одного параметра, на вкладке СКД "параметры" вы всё равно увидите стандартный параметр(по моему "период", но не уверен), он может быть не заполнен!)
По оптимизации: после обработки СКД старого запроса, количество таблиц так и осталось или их стало меньше?)
Если используются пользовательские отборы, то умная СКД догадывается их впиндюрить в параметры виртуальных таблиц. Это если мы говорим о режиме автозаполения настроек СКД и стандартных названиях полей.
(6) есть еще ситуация с кэшированием. 1 раз выполнили запрос, затем если его повторно вызвать, то будет уже быстрее. Посмотрите курс по запросам, возможно вам этого не хватает для разработки!
(10) Да не стоят. Но тут уже вопрос принципа. Я день убил ускоряя работу запроса, добился эффективности в 26 раз. А в итоге все в пустую, хочу понять перво причину. С тем что исходный запрос срабатывает быстрее, думаю разобрался, все из-за того, что "умного СКД которая впендюривает параметры отбора во временные таблицы".
Но почему мой запрос работает дольше? Мне это не понятно.
(11) Ты не говорил про дольше. Ты говорил про "те же 5 секунд". Просто отборы сводят размер обрабатываемых данных до таких, на которых оптимизация еще не дает эффекта. Там ведь зависимость может еще и нелинейная быть.
Закинь свою схему компоновки в консоль КД и посмотри какой запрос на самом деле выполняет твой отчёт при настроенном отборе! Думаю что по факту вы получите ваш же оптимизированный запрос(ну или примерно его)!
СКД меняет запрос в зависимости от отборов, выходных полей итд!
Я так понимаю, это и есть изменения которые внес СКД, но они стоят там где указывается период в РН.Обороты. Но я указываю только один параметр отбора с типом Справочник. Так что же это за П ?
Работал себе запрос. Всех устраивало. Нет надо залезть все сломать и потом на форуме удивляться почему не стало лучше. мне бы такую работ. Сидишь ничего не делаешь, код оптимизируешь...
Да еще и предыдущего программиста обложили нехорошими словами наверное..
Да, по первому подзапросу начнет работать оптимизатор SQL уже. Теперь он сможет предложить эффективный план запроса, если на нужных полях окажутся индексы. Но я подозреваю, что и этот и следующий запрос оба являются ошибкой проектирования.
База 1С должна быть спроектирована так, что бы все запросы шли исключительно по регистрам. Естественно, возможны исключения. Но не там, где у вас запросы выполняются 5 и 26 секунд.
По второму подзапросу:
1. РегистрНакопления.СИТ_ЗаказыПоСтроительнымСпецификациямВСЗС.Обороты(, , Регистратор, ЭлементСпецификации В (ВЫБРАТЬ ЭлементСтроительнойСпецификации ИЗ втСС КАК втСС)) - надо это или нет, зависит от специфики таблиц.
2. Выборка из любого периодического регистра должна в первую очередь ограничиваться периодом. Поэтому параметры периодов делаем обязательными, а в особо тяжёлых случаях, ограничиваем у пользователя возможность формировать данные за 15 лет.
3. А там точно необходимо левое соединение? А оно не обрезается нигде позже?
Не СКД портит, а запрос такой. Я прикопался к первым 5 пакетам просто потому что разбирать дальше у меня нет времени и возможности. А вообще, не исключено, что 1-5 пакет вообще не нужен, так же как не нужен 1-3. Ну разве что, у вас SQL-Server 2000 и ниже.