При работе с большими объемами данных в 1С, такими как справочник Номенклатура, разработчики часто сталкиваются с проблемой медленного поиска. Одним из основных инструментов решения этой задачи является индексирование. В этой статье мы подробно разберем, что такое индекс с точки зрения SQL-сервера, как он выглядит «под капотом», и к каким последствиям (как положительным, так и отрицательным) приводит его использование.
Для начала проанализируем самую простую аналогию, которая помогает понять суть процесса. Представьте себе большую советскую энциклопедию, состоящую из 50 томов. Если вам нужно найти информацию о конкретном термине, вы не будете перелистывать каждый том страница за страницей. Вы возьмете отдельный «указательный» том (индекс), найдете там слово по алфавиту и увидите номер тома и страницы. Индекс в SQL работает по тому же принципу: это вспомогательная структура, которая хранит отсортированные значения индексируемого поля и ссылки на соответствующие строки в основной таблице данных.
Рассмотрим, что происходит на уровне СУБД, когда мы устанавливаем галочку «Индексировать» у реквизита в 1С. Вопреки некоторым предположениям, это не просто «колонка со звездочкой». Физически это отдельный объект базы данных.
С точки зрения хранения данных выделяют два основных типа индексов:
Ссылка (GUID). У таблицы может быть только один кластерный индекс.В SQL-сервере 1С дает этим структурам системные имена. Например, основная таблица справочника может называться _Reference25, а индекс по вашему новому реквизиту — _Reference25_ByField1234_R. Проанализируем ситуацию: создавая индекс, мы фактически дублируем часть данных, что неизбежно ведет к росту объема базы данных.
Разберем практический пример из обсуждения. При загрузке данных из XML-файла выполняется поиск товара по определенному идентификатору (реквизиту). Если поле не проиндексировано, система выполняет Table Scan — полное сканирование таблицы. Если в справочнике миллионы записей, поиск каждой позиции будет занимать значительное время.
После включения индексации ситуация меняется:
INSERT) или изменении индексированного поля (UPDATE) SQL-сервер вынужден обновлять не только основную таблицу, но и все связанные с ней индексы. Чем больше индексов, тем медленнее работает запись данных.Рассмотрим фрагмент кода, который часто становится причиной замедления при загрузке данных:
// Медленный вариант поиска в цикле
Для Каждого СтрокаXML Из ДанныеXML Цикл
ТоварСсылка = Справочники.Номенклатура.НайтиПоРеквизиту("ИдентификаторИзXML", СтрокаXML.ID);
// Обработка
КонецЦикла;
Проанализируем этот подход. Даже с индексом, вызов НайтиПоРеквизиту внутри цикла порождает тысячи отдельных обращений к серверу БД. Мы можем оптимизировать этот процесс «малой кровью», используя временные таблицы и запросы.
Посмотрим на более эффективный алгоритм:
ТаблицаЗначений.
// Эффективный вариант с использованием запроса
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ВТ_ДанныеXML.ID КАК ID,
| Номенклатура.Ссылка КАК Ссылка
|ПОМЕСТИТЬ ВТ_Идентификаторы
|ИЗ
| &ТаблицаИдентификаторов КАК ВТ_ДанныеXML
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ВТ_Идентификаторы.ID,
| Номенклатура.Ссылка
|ИЗ
| ВТ_Идентификаторы КАК ВТ_Идентификаторы
| ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Номенклатура
| ПО ВТ_Идентификаторы.ID = Номенклатура.ИдентификаторИзXML";
Запрос.УстановитьПараметр("ТаблицаИдентификаторов", ТЗ_Идентификаторы);
РезультатЗапроса = Запрос.Выполнить().Выгрузить();
Такой подход позволяет одним «выстрелом» получить соответствия для всех строк XML, что на больших объемах работает значительно быстрее, чем поиск в цикле.
Важно помнить, что индексы требуют ухода. Со временем, при активном изменении данных, возникает фрагментация. Данные в индексе начинают лежать вперемешку, возникают пустые «дыры» на страницах памяти. Чтобы индекс не терял эффективности, необходимо выполнять регламентные операции в SQL-сервере:
В 1С для этих целей существуют регламентные задания, но для клиент-серверных баз лучше настраивать планы обслуживания непосредственно на стороне SQL-сервера.
Выясним причины, по которым избыточное индексирование вредно:
Подведем итог: использование индексов в 1С — это мощный инструмент оптимизации. Правильно установленная галочка «Индексировать» может превратить «зависающую» загрузку данных в мгновенную операцию. Однако всегда стоит помнить о балансе между скоростью поиска и нагрузкой на систему при записи данных, а также не забывать о регулярном обслуживании базы данных.