Нужно ли индексировать поля временной таблицы при соединении в запросах 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке сложных отчетов или обработок на платформе 1С:Предприятие программисты часто сталкиваются с необходимостью передачи внешних данных (например, из ТаблицыЗначений) в запрос. Для этого данные помещаются во временную таблицу, которая затем участвует в соединениях. Возникает закономерный вопрос: нужно ли индексировать поля этой таблицы для ускорения работы запроса? Рассмотрим эту ситуацию подробно, опираясь на технические стандарты 1С и механизмы работы СУБД.

Различие между временными и виртуальными таблицами

Прежде всего, проанализируем терминологию, так как в среде разработчиков часто возникает путаница. Выясним причину, почему это важно:

В примере автора сообщения речь идет именно о временной таблице, создаваемой из параметра &ТаблицаДанных. Для таких таблиц правила индексации имеют свои критические нюансы.

Когда индексирование действительно необходимо

Рассмотрим основной стандарт оптимизации: создание индекса для временной таблицы оправдано только в том случае, если в ней содержится значительное количество записей. Официальный порог, рекомендуемый фирмой 1С, составляет 1000 записей.

Проанализируем ситуацию: если в вашей временной таблице всего 10–50 строк (например, список товаров в одном документе), время, затраченное СУБД на построение индекса в TempDB, может превысить выгоду от его использования. В этом случае СУБД быстрее выполнит полное сканирование (Table Scan) в оперативной памяти. Однако если записей больше тысячи, индекс становится обязательным для предотвращения деградации производительности.

Индексирование в левом соединении

Посмотрим на пример кода из обсуждения, где временная таблица выступает «левой» (основной) в ЛЕВОМ СОЕДИНЕНИИ:


ВЫБРАТЬ
    ВиртуальнаяТаблица.Номенклатура,
    ШтрихкодыНоменклатуры.Штрихкод
ИЗ
    ВиртуальнаяТаблица КАК ВиртуальнаяТаблица
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ШтрихкодыНоменклатуры КАК ШтрихкодыНоменклатуры
    ПО ВиртуальнаяТаблица.Номенклатура = ШтрихкодыНоменклатуры.Номенклатура

В этой структуре ВиртуальнаяТаблица является ведущей. Оптимизатор СУБД чаще всего выбирает один из двух алгоритмов соединения:

  1. Nested Loops (Вложенные циклы): СУБД берет каждую строку из левой таблицы и ищет соответствие в правой. В этом случае индекс на левой таблице не используется, так как она сканируется целиком. Здесь критически важно наличие индекса на правой таблице (в нашем случае — на регистре штрихкодов).
  2. Merge Join (Соединение слиянием): Этот алгоритм требует, чтобы обе таблицы были отсортированы по полям соединения. Вот здесь наличие индекса на временной таблице может помочь, так как СУБД возьмет уже готовые отсортированные данные из индекса, не тратя ресурсы на предварительную сортировку в памяти.

Важность типизации через ВЫРАЗИТЬ

Разберем крайне важный момент, упомянутый в дискуссии: явная типизация полей. Даже если ваша ТаблицаЗначений типизирована в коде 1С, при передаче в запрос поля могут быть восприняты как составные типы, если есть хоть малейшая неопределенность в метаданных.

Если поле (например, Характеристика) имеет составной тип, СУБД создает в SQL-таблице несколько колонок для хранения ссылок и типов. При соединении это заставляет систему выполнять дополнительные проверки, что резко замедляет запрос. Чтобы этого избежать, всегда используйте конструкцию ВЫРАЗИТЬ при формировании временной таблицы:


ВЫБРАТЬ
    ВЫРАЗИТЬ(ТаблицаДанных.Номенклатура КАК Справочник.Номенклатура) КАК Номенклатура,
    ВЫРАЗИТЬ(ТаблицаДанных.Характеристика КАК Справочник.ХарактеристикиНоменклатуры) КАК Характеристика
ПОМЕСТИТЬ ВТ_Данные
ИЗ
    &ТаблицаДанных КАК ТаблицаДанных
ИНДЕКСИРОВАТЬ ПО
    Номенклатура,
    Характеристика

Это гарантирует, что в базе данных будет создана колонка строго определенного типа, что максимально упростит работу оптимизатора СУБД.

Новые возможности платформы (8.3.25 и выше)

Для тех, кто работает на современных версиях платформы, появились дополнительные инструменты оптимизации временных таблиц, которые полезно знать:

Подведем итоги и сформируем рекомендации

Проанализировав ситуацию, мы можем составить следующий чек-лист для работы с временными таблицами:

  1. Оценивайте объем данных: Если во временной таблице ожидается более 1000 строк — индексируйте обязательно. Если меньше — индексация может быть избыточной, но обычно не вредит (кроме случаев сверхвысокой частоты вызова коротких запросов).
  2. Всегда типизируйте поля: Используйте ВЫРАЗИТЬ для всех ссылочных полей во временной таблице, особенно если они участвуют в условиях соединения (ПО...) или отбора (ГДЕ...).
  3. Проверяйте правую таблицу: При ЛЕВОМ СОЕДИНЕНИИ в первую очередь убедитесь, что проиндексированы поля в присоединяемой таблице (индексы в метаданных конфигурации).
  4. Избегайте NULL: Как заметили участники обсуждения, при левом соединении всегда помните о возможной обработке NULL значений, если соответствие не будет найдено.

Соблюдение этих правил позволит вашим запросам работать стабильно быстро даже при росте объема базы данных и усложнении логики учета.

← На главную