При разработке отчетов и обработок в 1С программисты часто сталкиваются с ситуацией, когда выполнение алгоритма останавливается на строке Запрос.Выполнить(). При этом в одной информационной базе запрос может отрабатывать за доли секунды, а в другой — намертво зависать. Разберем причинно-следственные связи этой проблемы и рассмотрим эффективные методы оптимизации запросов к остаткам и оборотам регистра бухгалтерии.
Рассмотрим пример запроса к виртуальной таблице регистра бухгалтерии, который может вызывать длительное зависание СУБД:
ВЫБРАТЬ
ТиповойОстаткиИОбороты.Субконто1 КАК Субконто1,
СУММА(ТиповойОстаткиИОбороты.СуммаНачальныйОстаток) КАК СуммаНачальныйОстаток,
СУММА(ТиповойОстаткиИОбороты.СуммаКонечныйОстаток) КАК СуммаКонечныйОстаток,
СУММА(ТиповойОстаткиИОбороты.СуммаОборотДт) КАК СуммаОборотДт,
СУММА(ТиповойОстаткиИОбороты.СуммаОборотКт) КАК СуммаОборотКт,
СУММА(ТиповойОстаткиИОбороты.КоличествоНачальныйОстаток) КАК КоличествоНачальныйОстаток,
СУММА(ТиповойОстаткиИОбороты.КоличествоКонечныйОстаток) КАК КоличествоКонечныйОстаток,
СУММА(ТиповойОстаткиИОбороты.КоличествоОборотДт) КАК КоличествоОборотДт,
СУММА(ТиповойОстаткиИОбороты.КоличествоОборотКт) КАК КоличествоОборотКт
ИЗ
РегистрБухгалтерии.Типовой.ОстаткиИОбороты(&Н, &К, Авто, , Счет В (&Счет), , Подразделение В (&Подразделение)) КАК ТиповойОстаткиИОбороты
СГРУППИРОВАТЬ ПО
ТиповойОстаткиИОбороты.Субконто1
На первый взгляд текст запроса синтаксически корректен, однако на практике вызов Запрос.Выполнить() приводит к зависанию по ряду технических причин. Выясним, почему это происходит и как исправить ошибку.
Субконто1 без явного указания списка видов субконто в параметрах виртуальной таблицы заставляет платформу выполнять соединение со всеми возможными таблицами справочников, настроенных для данного плана счетов.В: Если в параметр &Счет или &Подразделение передается группа (родительский элемент), оператор В не выбирает подчиненные элементы и может приводить к неоптимальному плану запроса.СГРУППИРОВАТЬ ПО совместно с агрегатными функциями СУММА по полям виртуальной таблицы ОстаткиИОбороты часто является избыточным, так как таблица уже отдает сгруппированные данные в соответствии с выбранной периодичностью.1. Пошаговая диагностика параметров
Для определения причин задержки рекомендуется последовательно отключать параметры виртуальной таблицы в коде. Уберите передачу параметров по одному (например, временно исключите отбор по подразделению или счету), чтобы понять, какое именно условие вызывает ложное сканирование таблиц СУБД (Table Scan).
2. Корректировка отборов и вынос условий
В некоторых сценариях платформа формирует некорректный план SQL-запроса при составных условиях внутри скобок параметризации виртуальной таблицы. Перенос сложного условия из параметров виртуальной таблицы в секцию ГДЕ (WHERE) или оптимизация состава параметров внутри скобок ОстаткиИОбороты(...) позволяет СУБД применить верные индексы.
3. Явное указание видов субконто и использование иерархии
Для правильного формирования запроса разберем следующие правила:
В используйте В ИЕРАРХИИ.ПланВидовХарактеристик.ВидыСубконто...). Это существенно сократит количество внешних соединений в SQL-запросе.Авто задавайте четкий уровень периодичности (например, Период, Месяц или Регистратор), если требуется детализация.Посмотрим на оптимизированный вариант запроса:
ВЫБРАТЬ
ТиповойОстаткиИОбороты.Субконто1 КАК Субконто1,
ТиповойОстаткиИОбороты.СуммаНачальныйОстаток КАК СуммаНачальныйОстаток,
ТиповойОстаткиИОбороты.СуммаКонечныйОстаток КАК СуммаКонечныйОстаток,
ТиповойОстаткиИОбороты.СуммаОборотДт КАК СуммаОборотДт,
ТиповойОстаткиИОбороты.СуммаОборотКт КАК СуммаОборотКт,
ТиповойОстаткиИОбороты.КоличествоНачальныйОстаток КАК КоличествоНачальныйОстаток,
ТиповойОстаткиИОбороты.КоличествоКонечныйОстаток КАК КоличествоКонечныйОстаток,
ТиповойОстаткиИОбороты.КоличествоОборотДт КАК КоличествоОборотДт,
ТиповойОстаткиИОбороты.КоличествоОборотКт КАК КоличествоОборотКт
ИЗ
РегистрБухгалтерии.Типовой.ОстаткиИОбороты(
&Н,
&К,
Период,
,
Счет В ИЕРАРХИИ (&Счет),
&МассивВидовСубконто,
Подразделение В ИЕРАРХИИ (&Подразделение)
) КАК ТиповойОстаткиИОбороты
4. Администрирование и пересчет итогов
Если запрос подвисает только в конкретной базе данных при аналогичном коде, обязательно выполните обслуживание базы. Перейдите в режиме Конфигуратора в меню Администрирование — Тестирование и исправление, выберите пункт Пересчет итогов и запустите выполнение. После обновления индексов и итогов регистра бухгалтерии вызов Запрос.Выполнить() будет отрабатывать штатно.