Вопрос индексации в 1С — это не просто техническая деталь, а фундамент производительности любой крупной системы. Часто начинающие разработчики сталкиваются с дилеммой: индексировать всё подряд или надеяться на оптимизатор СУБД. В рамках этой статьи мы подробно разберем, когда создание индекса действительно ускоряет работу, как СУБД обрабатывает различные виды соединений и какие нюансы стоит учитывать при работе с временными таблицами.
Разберем ситуацию, которая часто вызывает споры: нужно ли индексировать таблицу, если в ней всего 4500 записей? Или, может быть, 100? В среде экспертов 1С существует эмпирическое правило: задумываться об индексации стоит, когда количество строк во временной таблице превышает 100–1000 записей.
Почему именно так? Проанализируем процесс: создание индекса — это не бесплатная операция. СУБД тратит время на построение дерева индекса, выделение места в tempdb и обновление системных статистик. Если данных мало, СУБД быстрее выполнит полное сканирование таблицы (Table Scan) в оперативной памяти, чем будет тратить ресурсы на работу с индексом. Однако для таблиц свыше 1000 строк отсутствие индекса может привести к катастрофическому падению производительности при соединениях.
Рассмотрим, какие поля и в каких таблицах нужно индексировать в зависимости от типа связи. Важно помнить, что в 1С порядок таблиц в запросе имеет значение для читаемости, но СУБД (SQL Server или PostgreSQL) может перестроить план выполнения по-своему.
ЛЕВОЕ СОЕДИНЕНИЕ, так как оно легче воспринимается человеком.Merge Join, который является наиболее эффективным для больших объемов данных.РегистрСведений.ИмяРегистра.СрезПоследних) превращаются в сложные подзапросы. Если вы соединяете временную таблицу с таким срезом, обязательно проиндексируйте поле связи во временной таблице. Это поможет оптимизатору эффективнее ограничить выборку из итогов регистра.Чтобы понимать, зачем мы ставим «галочку» индексации, разберем, что происходит «под капотом» СУБД. Оптимизатор выбирает один из трех основных методов соединения:
1. Вложенные циклы (Nested Loops). Рассмотрим ситуацию: одна таблица очень маленькая, а вторая — огромная. СУБД берет строку из маленькой таблицы и ищет её в большой. Если большая таблица проиндексирована по полю связи, поиск происходит мгновенно (Index Seek). Если индекса нет, СУБД придется каждый раз сканировать всю огромную таблицу целиком, что приведет к зависанию запроса.
2. Соединение слиянием (Merge Join). Этот метод требует, чтобы обе таблицы были заранее отсортированы по полям связи. Поскольку индекс в 1С — это и есть физически отсортированные данные, наличие индексов на обеих таблицах позволяет СУБД просто «пройтись» по двум спискам одновременно. Это самый быстрый способ для соединения миллионных таблиц.
3. Хеш-соединение (Hash Join). Используется, когда индексов нет. СУБД строит в памяти хеш-таблицу. Проанализируем риск: если данных много и памяти не хватит, СУБД начнет сбрасывать данные на диск (в tempdb), что замедлит работу в десятки раз. Индексация помогает избежать этого сценария.
Посмотрим на продвинутый прием. В сообщении №6 упоминалось, что чтение некластерного индекса быстрее, чем кластерного. Если ваш индекс во временной таблице содержит не только поля связи, но и те поля, которые вы выбираете в секции ВЫБРАТЬ, СУБД вообще не будет обращаться к самой таблице. Она возьмет все нужные данные прямо из «листьев» индекса. В 1С это достигается созданием индекса по нескольким полям в правильном порядке.
Выясним, что такое Table Spool и как индексы помогают от него избавиться. Иногда в плане запроса можно увидеть операцию «Spool» — это временное сохранение промежуточных результатов на диск, потому что СУБД «боится» потерять результат вычисления сложного подзапроса. Индексация полей соединения во временных таблицах — это основной инструмент разработчика, позволяющий подсказать оптимизатору, что данные уже упорядочены и доступны, избавляя систему от лишней нагрузки на дисковую подсистему. Для выявления подобных проблем и оценки нагрузки можно использовать инструмент для анализа SQL-сервера и выполняемых запросов.
Разберем по шагам, как эффективно индексировать временные таблицы в пакете запросов:
Склад и Номенклатура, индекс должен быть именно в таком порядке (или наоборот), но обязательно содержать оба поля. Если вы проиндексируете только Склад, а соединять будете по Номенклатуре, индекс не сработает.Table Scan (полное сканирование) на больших объемах — это главный сигнал к тому, что индекс необходим.Проанализировав вышесказанное, мы видим, что индексация — это инструмент точечной настройки. Используйте её осознанно для таблиц с объемом более 100-500 строк и всегда отдавайте приоритет индексации тех полей, которые участвуют в секции ГДЕ и ПО (условия соединения).