Оптимизация запросов 1С с соединениями виртуальных таблиц регистров
- Критическое замедление отчетов и алгоритмов проведения при обращении к виртуальным таблицам (
РегистрНакопления...Остатки). - В планах SQL наблюдается полное сканирование (Table Scan/Index Scan) всей таблицы итогов регистра вместо Index Seek.
- В ТЖ фиксируются длительные события
DBMSSQL/DBPOSTGRSна вычисление остатков по всей номенклатуре.
1. Проблема неоптимального запроса (Антипаттерн)
Никогда не передавайте условия связи через секцию ГДЕ или ПО при соединении с виртуальной таблицей:
// НЕПРАВИЛЬНО: Виртуальная таблица рассчитает остатки по ВСЕЙ базе данных!
ВЫБРАТЬ Документ.Номенклатура, Остатки.КоличествоОстаток
ИЗ Документ.ЗаказКлиента.Товары КАК Документ
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки(&Период, ) КАК Остатки
ПО Документ.Номенклатура = Остатки.Номенклатура;2. Правильный паттерн: Фильтрация в параметрах виртуальной таблицы
// ПРАВИЛЬНО (Вариант 1): Если отбор по фиксированному списку
ВЫБРАТЬ Документ.Номенклатура, Остатки.КоличествоОстаток
ИЗ Документ.ЗаказКлиента.Товары КАК Документ
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки(&Период, Номенклатура В (&МассивНоменклатуры)) КАК Остатки
ПО Документ.Номенклатура = Остатки.Номенклатура;3. Правильный паттерн: Использование временной таблицы с отбором
// ПРАВИЛЬНО (Вариант 2): Выгрузка уникального состава во временную таблицу с индексом
ВЫБРАТЬ РАЗЛИЧНЫЕ
Док.Номенклатура КАК Номенклатура
ПОМЕСТИТЬ ВТ_Товары
ИЗ &ТабличнаяЧасть КАК Док;
ИНДЕКСИРОВАТЬ ПО Номенклатура;
ВЫБРАТЬ
ВТ.Номенклатура,
Остатки.КоличествоОстаток
ИЗ ВТ_Товары КАК ВТ
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки(&Период, Номенклатура В (ВЫБРАТЬ ВТ.Номенклатура ИЗ ВТ_Товары КАК ВТ)) КАК Остатки
ПО ВТ.Номенклатура = Остатки.Номенклатура; Частые вопросы (FAQ)
Почему нельзя накладывать условие на виртуальную таблицу в секции ГДЕ?
Условие в секции ГДЕ накладывается уже ПОСЛЕ того, как СУБД полностью рассчитала итоги по всей таблице регистра. Передача условия в параметры виртуальной таблицы заставляет платформу внедрить фильтр прямо в подзапрос к таблице итогов.
Нужно ли индексировать временную таблицу, используемую в параметрах виртуальной таблицы?
Да, если во временной таблице содержится более нескольких десятков записей, индексация по полям соединения обязательна для использования эффективного Nested Loops / Index Seek в СУБД.
Как работают виртуальные таблицы оборотов при отсутствии параметров периодичности?
Виртуальные таблицы оборотов обращаются к таблице движений напрямую или к таблице итогов оборотов (если включена). Без указания границ периода СУБД выполнит полное сканирование регистра.
Можно ли соединять две виртуальные таблицы между собой напрямую?
Прямое соединение двух виртуальных таблиц без предварительной выгрузки во временные таблицы является грубой ошибкой разработки 1С, многократно увеличивающей время формирования запроса.