Как оптимизировать производительность регистра «ДанныеВнутреннихДокументов» в 1С:Документооборот при помощи индексов?

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

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

Понимание структуры индексов платформы 1С

Прежде чем изменять свойства метаданных, нам необходимо четко понимать, как именно платформа 1С:Предприятие транслирует наши настройки в физические индексы СУБД (SQL Server, PostgreSQL и др.). Когда мы устанавливаем признак Индексировать у ресурса регистра сведений, платформа не просто создает индекс по этому полю. Рассмотрим внутреннюю механику построения индекса.

Согласно методологии 1С, для ресурса создается составной индекс по следующей схеме: [Ресурс] + [Измерение 1] + [Измерение 2] + ... + [Измерение N]

Проанализируем ситуацию автора: в регистре ДанныеВнутреннихДокументов есть 3 измерения. Это означает, что каждый новый индекс будет содержать в себе как минимум четыре поля. Если мы проиндексируем еще 3 ресурса, мы добавим 3 полноценных составных индекса. Это значительно увеличивает нагрузку на дисковую подсистему при любой операции записи в регистр.

Анализ селективности данных перед индексацией

Разберем понятие селективности. Селективность — это отношение количества уникальных значений в поле к общему количеству записей. Чем выше селективность, тем эффективнее будет работать индекс. Выясним причину, по которой индексация некоторых полей может быть бесполезной:

  1. Поля типа Булево (например, НеТребуется): Селективность крайне низкая (всего два варианта: Истина или Ложь). Если в базе 1 000 000 документов и у 900 000 из них значение «Ложь», то при поиске по значению «Ложь» SQL-оптимизатор, скорее всего, проигнорирует индекс и выполнит Table Scan (полное сканирование таблицы), так как это быстрее, чем читать индекс и потом обращаться к основной таблице за данными.
  2. Поля типа Дата (например, ДатаОкончанияДействия, СрокИсполнения): Эти поля обладают высокой селективностью. Индексировать их полезно, но только если они используются в запросах в «чистом» виде, без преобразований.

Рассмотрим пример кода, где индекс по дате не будет работать эффективно из-за использования функций на стороне СУБД:


ГДЕ
    НАЧАЛОПЕРИОДА(Регистр.СрокИсполнения, ДЕНЬ) = &НужнаяДата

Чтобы индекс использовался, перепишем условие так:


ГДЕ
    Регистр.СрокИсполнения МЕЖДУ &НачалоДня И &КонецДня

Риски избыточного индексирования (Index Overhead)

Проанализируем ситуацию с «раздуванием» таблицы. Регистр ДанныеВнутреннихДокументов уже содержит 58 ресурсов, 13 из которых проиндексированы. Каждая новая запись в этот регистр (а он обновляется фоновым заданием при любом изменении документа) требует обновления всех существующих индексов.

Основные проблемы при избытке индексов:

Пошаговый алгоритм принятия решения об индексации

Разберем шаги, которые помогут нам принять взвешенное решение:

  1. Проверка текущей статистики: Выполним запрос к базе данных, чтобы понять распределение значений. Если записей с пометкой удаления или истекшим сроком очень мало по сравнению с общим объемом, индекс по этим критериям будет «выстреливать» очень эффективно.
  2. Замер производительности (APDEX): Замерим время выполнения виджета «Мои документы» до внесения изменений.
  3. Использование консоли запросов с планом запроса: Посмотрим, какой план строит SQL-сервер. Если мы видим Clustered Index Scan, значит, система сканирует всю таблицу целиком.
  4. Частичная индексация: Вместо добавления сразу трех индексов, попробуем проиндексировать только один — самый селективный (например, СрокИсполнения).
  5. Повторный замер: Проверяем, изменился ли план запроса на Index Seek.

Альтернативные способы решения проблемы

Рассмотрим варианты, как ускорить выборку данных для виджетов без добавления тяжелых индексов в основной регистр:

1. Использование проиндексированных измерений

Если в вашем запросе есть возможность добавить фильтр по одному из измерений (например, Документ или Владелец), это может значительно сузить область поиска, и SQL-серверу будет проще обработать неиндексированные ресурсы в рамках уже найденных строк.

2. Создание вспомогательного регистра-фильтра

Вместо того чтобы нагружать таблицу с 58 ресурсами, можно создать небольшой вспомогательный регистр сведений, где будет всего 2-3 измерения и минимум ресурсов. Данные в него можно записывать одновременно с основным регистром. Поиск по узкой таблице всегда будет быстрее, чем по широкой.

3. Оптимизация текста запроса

Выясним, действительно ли нам нужны все данные из регистра. Часто разработчики выбирают «все поля» через * или выбирают лишние ресурсы. Проанализируем запрос в ТекущиеДелаДокументооборотСервер.ЗаполнитьВиджетМоиДокументы. Если мы ищем документы, которые «Не требуется» и «Срок не истек», возможно, стоит объединить эти условия или проверить логику их заполнения.

Заключение и итоговая стратегия

Подведем итог нашего исследования. Добавление трех индексов в регистр ДанныеВнутреннихДокументов может как помочь, так и серьезно навредить системе.

Рекомендованная стратегия:

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

← На главную