Индексы в 1С:Предприятии — настройка и обслуживание
Содержание
Навесить индекс на каждый реквизит, чтобы «всё летало» — самая частая ошибка при оптимизации. Каждый лишний индекс замедляет запись и проведение документов, а место в базе растёт. Индексы ускоряют только чтение, и ставить их нужно адресно — под конкретные медленные запросы.
Платформа 8.3 работает поверх реляционной СУБД (MS SQL Server или PostgreSQL), и часть индексов она строит сама по правилам хранения объектов. Разработчику остаётся добавить недостающие: через свойства в конфигураторе или, в тяжёлых случаях, напрямую в СУБД. Ниже — как это устроено и что с чем не перепутать.
Что платформа индексирует автоматически
Каждый объект метаданных (справочник, документ, регистр) платформа раскладывает в одну или несколько таблиц СУБД. Для многих из них индексы создаются без участия разработчика:
- 🔑 По внутренней ссылке — у всех ссылочных объектов. По ней идёт переход «по ссылке» и соединения в запросах.
- 🔤 По коду и наименованию справочника, если для них включён контроль уникальности или они участвуют в основном представлении.
- 📊 По измерениям регистров — для регистра сведений строится индекс по набору измерений, для регистра накопления — по регистратору и по измерениям, участвующим в итогах.
- 🕒 По периоду и регистратору — у периодических регистров сведений и у движений.
Эти индексы закрывают типовые сценарии: поиск по ссылке, получение остатков, отбор движений по регистратору. Проблемы начинаются там, где запрос фильтрует данные по полю, которое платформа индексировать не стала — например, по дополнительному реквизиту документа или по строковому полю справочника.
Прежде чем добавлять свой индекс, убедитесь, что нужного нет среди служебных. Лишний индекс-дубль только тормозит запись.
Как понять, что запросу не хватает индекса
Признак один: выборка по непустому условию отбора работает заметно дольше, чем должна, и время растёт вместе с размером таблицы. Это сканирование таблицы целиком вместо точечного обращения по индексу.
Чем смотреть:
- Замер производительности в конфигураторе (
Отладка → Замер производительности) — показывает, какие строки кода и запросы съедают время в конкретном сценарии. - Технологический журнал платформы — события
DBMSSQLиDBPOSTGRSсодержат текст запроса к СУБД и его длительность. - Средства самой СУБД. В MS SQL Server — план выполнения и Query Store; в PostgreSQL —
EXPLAIN (ANALYZE)по тексту запроса. В плане ищите полное сканирование (Table Scan/Index ScanпротивSeq Scan).
В плане запроса видно, использовал ли оптимизатор индекс или прочитал всю таблицу. Полное сканирование большой таблицы на горячем участке кода — прямой кандидат на индексацию поля из условия ГДЕ или из соединения.
Если нужна системная картина, а не разбор одного сценария, помогает расчёт APDEX: по типовым операциям собираются замеры времени, и видно, какие из них вышли за целевой порог. В клиент-серверном варианте нагрузку по запросам удобно смотреть через центр управления производительностью (ЦУП). Но для точечной задачи «почему тормозит вот этот отчёт» быстрее всего именно замер в конфигураторе плюс план запроса в СУБД.
Частый сценарий: отчёт с отбором по дополнительному реквизиту документа работает секунды на тысяче строк и минуты на миллионе. В плане — полное сканирование таблицы документа. Решение почти всегда одно: включить индексацию этого реквизита. После обновления структуры тот же отчёт отрабатывает за доли секунды, потому что СУБД читает не всю таблицу, а узкий диапазон индекса.
Текст запроса в СУБД отличается от текста на языке запросов 1С: имена таблиц и полей — служебные (_Reference123, _Fld456). Сопоставить их помогает структура хранения — её можно выгрузить методом ПолучитьСтруктуруХраненияБазыДанных().
Индексирование реквизитов и измерений в конфигураторе
Это штатный и безопасный путь. У большинства реквизитов есть свойство «Индексировать» с тремя значениями:
- Не индексировать — по умолчанию.
- Индексировать — строится индекс по этому полю. Подходит, когда по реквизиту идёт отбор.
- Индексировать с дополнительным упорядочиванием — в индекс добавляются поля, по которым объект обычно сортируется (код/наименование у справочника, дата у документа). Берите этот вариант, если по полю не только фильтруют, но и упорядочивают результат.
Где искать свойство: откройте реквизит в дереве конфигурации (Общие → ... или внутри нужного объекта) и в палитре свойств найдите Индексирование.
Отдельно стоит индексирование измерений регистров сведений: у измерения есть свойство Индексировать, и включать его стоит, когда по измерению идёт отбор без указания ведущих измерений. Для реквизитов плана видов характеристик и дополнительных сведений действует та же логика.
Ещё одна точка, про которую забывают, — динамические списки. Форма списка справочника или документа с отбором или сортировкой по неиндексированному полю тормозит так же, как отчёт. Если пользователи постоянно отбирают список по какому-то реквизиту, этот реквизит стоит проиндексировать: платформа строит запрос списка с учётом индекса и подгружает данные порциями быстрее.
Отбор, заложенный в объект через основной отбор регистров и через критерии отбора, тоже опирается на индексы. Поэтому поля, участвующие в таких механизмах, обычно уже индексируются платформой — добавлять им индекс вручную не нужно.
После изменения свойства индекс не появится сам — нужно обновить структуру базы данных:
Конфигурация → Обновить конфигурацию базы данных(или F7).- Платформа покажет список изменений, включая реструктуризацию таблиц.
- Реструктуризация больших таблиц идёт долго и требует монопольного доступа к базе — на это время другие пользователи работать не смогут.
Обновление структуры крупных таблиц выполняйте в нерабочее время и только после резервной копии. На таблице с десятками миллионов строк перестроение может занять часы, а откатить его штатно нельзя.
Создание индекса напрямую в СУБД: когда и чем рискуете
Иногда управляемого индекса недостаточно: нужен составной индекс по нестандартному набору полей или фильтрующий (partial) индекс, которого платформа не умеет создавать. Тогда индекс делают средствами самой СУБД — командой CREATE INDEX по служебной таблице.
Выглядит это примерно так (имена таблиц и полей берутся из структуры хранения):
-- MS SQL Server, некластерный индекс по служебному полю
CREATE NONCLUSTERED INDEX IX_MyDoc_Contr
ON dbo._Document123 (_Fld456RRef)
INCLUDE (_Date_Time);
-- PostgreSQL, аналогичный индекс
CREATE INDEX ix_mydoc_contr
ON _document123 (_fld456rref);
Прежде чем так делать, взвесьте риски:
- 🧨 Индекс не переживёт реструктуризацию. Когда платформа перестроит таблицу (при обновлении конфигурации, затрагивающем её структуру), она создаст таблицу заново — ваш ручной индекс пропадёт. Его придётся пересоздавать и держать список таких индексов отдельно.
- 🚫 Это вне штатной поддержки 1С. Прямое вмешательство в структуру БД официально не поддерживается; при обращении в поддержку такие изменения могут посчитать причиной проблемы.
- ⚖️ Платформа о нём не знает. Оптимизатор СУБД индекс увидит и использует, но механизмы платформы с ним не считаются.
Поэтому ручной индекс — крайняя мера для конкретного «горячего» запроса, который не удалось разогнать штатными средствами. Сначала всегда пробуйте свойство «Индексировать».
Настройка полнотекстового поиска по данным
Полнотекстовый поиск (ППД) — это отдельный механизм платформы, не тот же самый, что индексы таблиц СУБД. Он позволяет искать по словам и их формам в строковых реквизитах: по наименованиям, комментариям, адресам, содержимому.
Чтобы он работал, нужны две вещи:
- Реквизиты помечены для полнотекстового поиска. У строковых реквизитов (и у реквизитов типа «Хранилище значения» для присоединённых файлов) в конфигураторе есть свойство
Полнотекстовый поиск— по умолчаниюИспользовать. Проверьте, что нужные поля из него не исключены. - Индекс ППД построен и поддерживается в актуальном состоянии. Это отдельный индекс, его надо периодически обновлять по мере изменения данных.
В типовых конфигурациях управление ППД вынесено в раздел администрирования (например, Администрирование → Обслуживание — точное название пункта зависит от конфигурации), а регулярное обновление делает регламентное задание. Если индекс долго не обновлялся, свежие данные в полнотекстовом поиске не находятся — помогает принудительное обновление индекса.
Полнотекстовый поиск умеет больше, чем точное совпадение строки:
- 🔎 поиск по словоформам — по запросу «договор» найдутся «договора», «договору» и т. п.;
- 〰️ нечёткий поиск — допускает опечатки, степень нестрогости задаётся при поиске;
- 🔗 поиск по присоединённым файлам — если включено индексирование содержимого файлов.
Именно поэтому ППД не заменяется обычным индексом СУБД: обычный индекс ускоряет сравнение полей, а ППД разбирает текст на слова и ищет по ним с учётом морфологии русского языка.
Если в типовой конфигурации управления ППД на виду нет, обновить индекс можно программно — методами объекта ПолнотекстовыйПоиск (например, ОбновитьИндекс). Это же делает и регламентное задание.
Для больших баз индекс ППД строят порциями, а полную переиндексацию запускают в нерабочее время — построение с нуля создаёт серьёзную нагрузку.
Регламентное обслуживание индексов
Индекс со временем фрагментируется: страницы данных перемешиваются, и выборка по нему замедляется. Плюс устаревает статистика, по которой оптимизатор СУБД выбирает план. Без регулярного обслуживания даже правильно поставленные индексы постепенно теряют эффективность.
Что входит в обслуживание на стороне СУБД:
| Операция | MS SQL Server | PostgreSQL | Когда |
|---|---|---|---|
| Снять лёгкую фрагментацию | REORGANIZE | REINDEX (онлайн-режим) | фрагментация примерно 5–30 % |
| Перестроить индекс | REBUILD | REINDEX | фрагментация выше ~30 % |
| Обновить статистику | UPDATE STATISTICS | ANALYZE | регулярно, особенно после массовых изменений |
| Очистить мусор | — | VACUUM / автовакуум | регулярно |
Пороги 5 % и 30 % — ориентир, а не жёсткое правило: на небольших таблицах фрагментацию можно игнорировать. Обслуживание удобно оформить регламентным заданием СУБД (план обслуживания и SQL Agent в MS SQL, cron с vacuumdb/скриптом в PostgreSQL) и запускать ночью.
Перестроение индексов и VACUUM FULL нагружают диск и могут блокировать таблицы. Запускайте их в окно обслуживания, когда пользователи не работают.
Управляемый индекс или индекс СУБД: что выбрать
Выбор между свойством «Индексировать» и ручным CREATE INDEX сводится к тому, переживёт ли индекс обновление конфигурации
и готовы ли вы его сопровождать.
Практичный порядок действий: сначала найдите конкретный медленный запрос замером, потом добавьте управляемый индекс, проверьте план выполнения в СУБД и убедитесь, что оптимизатор его подхватил. К ручным индексам переходите, только когда штатных средств не хватило.
Индекс помогает не всегда. Если условие отбора возвращает почти всю таблицу (например, фильтр по полю, у которого два-три возможных значения), оптимизатор СУБД сознательно выберет полное сканирование — читать по индексу половину таблицы медленнее, чем всю подряд. Не ускорят индексы и запрос, который сам по себе тянет из базы миллионы строк: тут проблема не в поиске, а в объёме выборки, и лечится она пересмотром алгоритма, а не новым индексом.