Рассмотрим типовую ситуацию, когда данные сначала помещаются во временную таблицу, а затем используются для фильтрации виртуальной таблицы регистра сведений или накопления с помощью оператора В (ВЫБРАТЬ ...). В качестве примера проанализируем следующий пакет запросов:
ВЫБРАТЬ
СправочникОбъекты.Поле1 КАК Поле1
ПОМЕСТИТЬ ВТ_ПараметрОтбор
ИЗ
Справочник.Объекты КАК СправочникОбъекты
;
ВЫБРАТЬ
Обороты.ПолеИзмерение КАК ПолеИзмерение,
Обороты.РесурсОборот КАК РесурсОборот
ИЗ
РегистрНакопления.ДвиженияОбъектов.Обороты(
,
,
,
ПолеИзмерение В
(ВЫБРАТЬ
ВТ_ПараметрОтбор.Поле1
ИЗ
ВТ_ПараметрОтбор КАК ВТ_ПараметрОтбор)
) КАК Обороты
Возникает практический вопрос: требуется ли индексировать поле Поле1 во временной таблице ВТ_ПараметрОтбор для обеспечения максимальной производительности?
Согласно официальным стандартам разработки платформы 1С, поля временной таблицы необходимо индексировать, если к временной таблице выполняется обращение через подзапрос оператора В (...). В индекс должны включаться те поля временной таблицы из списка выборки, которые находятся с правой стороны оператора условия.
Рассмотрим, почему это критично на уровне СУБД (например, MS SQL Server или PostgreSQL):
В (ВЫБРАТЬ ...) преобразует подзапрос в операцию полусоединения (Semi-Join) или внутреннего соединения (Inner Join). По этой причине выборка из временной таблицы сопоставляется с физическими индексами таблиц баз данных.Nested Loops вместо ресурсоемкого Hash Join).При использовании подзапросов внутри параметров виртуальных таблиц важно соблюдать жесткие ограничения платформы 1С. При их нарушении платформе не удается эффективно развернуть виртуальную таблицу в SQL-запрос, что приводит к неоптимальному плану выполнения:
Проанализируем альтернативные подходы к построению запроса, которые помогают снизить нагрузку на системную базу данных TempDB и повысить скорость обработки:
Запрос.УстановитьПараметр("МассивОбъектов", МассивЗначений);
В тексте запроса условие принимает вид ПолеИзмерение В (&МассивОбъектов). Это исключает накладные расходы на создание структуры временной таблицы, вставку данных и её удаление.
ВЫБРАТЬ
СправочникОбъекты.Поле1 КАК Поле1
ПОМЕСТИТЬ ВТ_ПараметрОтбор
ИЗ
Справочник.Объекты КАК СправочникОбъекты
ИНДЕКСИРОВАТЬ ПО
Поле1
;
ВЫБРАТЬ
Движения.ПолеИзмерение КАК ПолеИзмерение,
Движения.Ресурс КАК Ресурс
ИЗ
ВТ_ПараметрОтбор КАК ВТ_ПараметрОтбор
ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрНакопления.ДвиженияОбъектов КАК Движения
ПО ВТ_ПараметрОтбор.Поле1 = Движения.ПолеИзмерение
Поле1 во временной таблице является обязательным условием для эффективного сопоставления записей.
Таким образом, при использовании выборки из временной таблицы в качестве подзапроса В (ВЫБРАТЬ ...) индексировать поле временной таблицы нужно, если объем данных превышает несколько десятков строк или требуется гарантировать стабильный и оптимальный план выполнения запроса СУБД.