Как работают индексы в 1С и SQL: влияние на производительность и структуру базы данных

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

При работе с большими объемами данных в 1С, такими как справочник Номенклатура, разработчики часто сталкиваются с проблемой медленного поиска. Одним из основных инструментов решения этой задачи является индексирование. В этой статье мы подробно разберем, что такое индекс с точки зрения SQL-сервера, как он выглядит «под капотом», и к каким последствиям (как положительным, так и отрицательным) приводит его использование.

Что такое индекс: аналогия из реального мира

Для начала проанализируем самую простую аналогию, которая помогает понять суть процесса. Представьте себе большую советскую энциклопедию, состоящую из 50 томов. Если вам нужно найти информацию о конкретном термине, вы не будете перелистывать каждый том страница за страницей. Вы возьмете отдельный «указательный» том (индекс), найдете там слово по алфавиту и увидите номер тома и страницы. Индекс в SQL работает по тому же принципу: это вспомогательная структура, которая хранит отсортированные значения индексируемого поля и ссылки на соответствующие строки в основной таблице данных.

Как индекс выглядит в SQL-таблице

Рассмотрим, что происходит на уровне СУБД, когда мы устанавливаем галочку «Индексировать» у реквизита в 1С. Вопреки некоторым предположениям, это не просто «колонка со звездочкой». Физически это отдельный объект базы данных.

С точки зрения хранения данных выделяют два основных типа индексов:

  1. Кластерный индекс: Это сама таблица, данные в которой физически упорядочены по определенному ключу. В 1С таким ключом обычно является Ссылка (GUID). У таблицы может быть только один кластерный индекс.
  2. Некластерный индекс: Это именно та «дополнительная таблица», которая создается при индексировании реквизитов. Она содержит копию данных из индексируемого поля, отсортированную для быстрого поиска, и «указатель» (в SQL это называется RID или ключ кластерного индекса), который говорит серверу, где лежит остальная часть строки.

В SQL-сервере 1С дает этим структурам системные имена. Например, основная таблица справочника может называться _Reference25, а индекс по вашему новому реквизиту — _Reference25_ByField1234_R. Проанализируем ситуацию: создавая индекс, мы фактически дублируем часть данных, что неизбежно ведет к росту объема базы данных.

Влияние индекса на производительность и объем данных

Разберем практический пример из обсуждения. При загрузке данных из XML-файла выполняется поиск товара по определенному идентификатору (реквизиту). Если поле не проиндексировано, система выполняет Table Scan — полное сканирование таблицы. Если в справочнике миллионы записей, поиск каждой позиции будет занимать значительное время.

После включения индексации ситуация меняется:

Оптимизация поиска: запросы против методов объекта

Рассмотрим фрагмент кода, который часто становится причиной замедления при загрузке данных:


// Медленный вариант поиска в цикле
Для Каждого СтрокаXML Из ДанныеXML Цикл
    ТоварСсылка = Справочники.Номенклатура.НайтиПоРеквизиту("ИдентификаторИзXML", СтрокаXML.ID);
    // Обработка
КонецЦикла;

Проанализируем этот подход. Даже с индексом, вызов НайтиПоРеквизиту внутри цикла порождает тысячи отдельных обращений к серверу БД. Мы можем оптимизировать этот процесс «малой кровью», используя временные таблицы и запросы.

Посмотрим на более эффективный алгоритм:

  1. Загружаем все идентификаторы из XML в ТаблицаЗначений.
  2. Передаем эту таблицу в запрос в качестве параметра.
  3. В запросе соединяем временную таблицу со справочником по индексированному полю.

// Эффективный вариант с использованием запроса
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	ВТ_ДанныеXML.ID КАК ID,
    |	Номенклатура.Ссылка КАК Ссылка
    |ПОМЕСТИТЬ ВТ_Идентификаторы
    |ИЗ
    |	&ТаблицаИдентификаторов КАК ВТ_ДанныеXML
    |;
    |
    |////////////////////////////////////////////////////////////////////////////////
    |ВЫБРАТЬ
    |	ВТ_Идентификаторы.ID,
    |	Номенклатура.Ссылка
    |ИЗ
    |	ВТ_Идентификаторы КАК ВТ_Идентификаторы
    |		ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Номенклатура
    |		ПО ВТ_Идентификаторы.ID = Номенклатура.ИдентификаторИзXML";

Запрос.УстановитьПараметр("ТаблицаИдентификаторов", ТЗ_Идентификаторы);
РезультатЗапроса = Запрос.Выполнить().Выгрузить();

Такой подход позволяет одним «выстрелом» получить соответствия для всех строк XML, что на больших объемах работает значительно быстрее, чем поиск в цикле.

Обслуживание индексов и статистика

Важно помнить, что индексы требуют ухода. Со временем, при активном изменении данных, возникает фрагментация. Данные в индексе начинают лежать вперемешку, возникают пустые «дыры» на страницах памяти. Чтобы индекс не терял эффективности, необходимо выполнять регламентные операции в SQL-сервере:

В 1С для этих целей существуют регламентные задания, но для клиент-серверных баз лучше настраивать планы обслуживания непосредственно на стороне SQL-сервера.

Когда не стоит создавать индексы?

Выясним причины, по которым избыточное индексирование вредно:

Подведем итог: использование индексов в 1С — это мощный инструмент оптимизации. Правильно установленная галочка «Индексировать» может превратить «зависающую» загрузку данных в мгновенную операцию. Однако всегда стоит помнить о балансе между скоростью поиска и нагрузкой на систему при записи данных, а также не забывать о регулярном обслуживании базы данных.

← На главную