При разработке сложных отчетов или обработок на платформе 1С:Предприятие программисты часто сталкиваются с необходимостью передачи внешних данных (например, из ТаблицыЗначений) в запрос. Для этого данные помещаются во временную таблицу, которая затем участвует в соединениях. Возникает закономерный вопрос: нужно ли индексировать поля этой таблицы для ускорения работы запроса? Рассмотрим эту ситуацию подробно, опираясь на технические стандарты 1С и механизмы работы СУБД.
Прежде всего, проанализируем терминологию, так как в среде разработчиков часто возникает путаница. Выясним причину, почему это важно:
РегистрНакопления.Остатки или РегистрСведений.СрезПоследних). Они не существуют в базе данных физически в том виде, в котором мы их видим в конструкторе запросов, а формируются «на лету» как сложные подзапросы.TempDB для MS SQL Server). Они существуют физически в рамках сеанса или работы менеджера временных таблиц.В примере автора сообщения речь идет именно о временной таблице, создаваемой из параметра &ТаблицаДанных. Для таких таблиц правила индексации имеют свои критические нюансы.
Рассмотрим основной стандарт оптимизации: создание индекса для временной таблицы оправдано только в том случае, если в ней содержится значительное количество записей. Официальный порог, рекомендуемый фирмой 1С, составляет 1000 записей.
Проанализируем ситуацию: если в вашей временной таблице всего 10–50 строк (например, список товаров в одном документе), время, затраченное СУБД на построение индекса в TempDB, может превысить выгоду от его использования. В этом случае СУБД быстрее выполнит полное сканирование (Table Scan) в оперативной памяти. Однако если записей больше тысячи, индекс становится обязательным для предотвращения деградации производительности.
Посмотрим на пример кода из обсуждения, где временная таблица выступает «левой» (основной) в ЛЕВОМ СОЕДИНЕНИИ:
ВЫБРАТЬ
ВиртуальнаяТаблица.Номенклатура,
ШтрихкодыНоменклатуры.Штрихкод
ИЗ
ВиртуальнаяТаблица КАК ВиртуальнаяТаблица
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ШтрихкодыНоменклатуры КАК ШтрихкодыНоменклатуры
ПО ВиртуальнаяТаблица.Номенклатура = ШтрихкодыНоменклатуры.Номенклатура
В этой структуре ВиртуальнаяТаблица является ведущей. Оптимизатор СУБД чаще всего выбирает один из двух алгоритмов соединения:
Разберем крайне важный момент, упомянутый в дискуссии: явная типизация полей. Даже если ваша ТаблицаЗначений типизирована в коде 1С, при передаче в запрос поля могут быть восприняты как составные типы, если есть хоть малейшая неопределенность в метаданных.
Если поле (например, Характеристика) имеет составной тип, СУБД создает в SQL-таблице несколько колонок для хранения ссылок и типов. При соединении это заставляет систему выполнять дополнительные проверки, что резко замедляет запрос. Чтобы этого избежать, всегда используйте конструкцию ВЫРАЗИТЬ при формировании временной таблицы:
ВЫБРАТЬ
ВЫРАЗИТЬ(ТаблицаДанных.Номенклатура КАК Справочник.Номенклатура) КАК Номенклатура,
ВЫРАЗИТЬ(ТаблицаДанных.Характеристика КАК Справочник.ХарактеристикиНоменклатуры) КАК Характеристика
ПОМЕСТИТЬ ВТ_Данные
ИЗ
&ТаблицаДанных КАК ТаблицаДанных
ИНДЕКСИРОВАТЬ ПО
Номенклатура,
Характеристика
Это гарантирует, что в базе данных будет создана колонка строго определенного типа, что максимально упростит работу оптимизатора СУБД.
Для тех, кто работает на современных версиях платформы, появились дополнительные инструменты оптимизации временных таблиц, которые полезно знать:
ИНДЕКСИРОВАТЬ ПО ... УНИКАЛЬНО. Если вы уверены, что строки во временной таблице не дублируются, это даст оптимизатору СУБД «подсказку», позволяющую строить еще более эффективные планы запроса.ИНДЕКСИРОВАТЬ ПО НАБОРАМ ((Поле1), (Поле2, Поле3)).Проанализировав ситуацию, мы можем составить следующий чек-лист для работы с временными таблицами:
ВЫРАЗИТЬ для всех ссылочных полей во временной таблице, особенно если они участвуют в условиях соединения (ПО...) или отбора (ГДЕ...).ЛЕВОМ СОЕДИНЕНИИ в первую очередь убедитесь, что проиндексированы поля в присоединяемой таблице (индексы в метаданных конфигурации).NULL значений, если соответствие не будет найдено.Соблюдение этих правил позволит вашим запросам работать стабильно быстро даже при росте объема базы данных и усложнении логики учета.