Почему включение итогов регистров накопления занимает несколько часов и как это исправить?

Программист 1С v8.3 (Обычные формы) Управленческий учет Промышленность, строительство и АПК
← На главную

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

Причина 1: Активность пользователей и блокировки в рабочей базе

Первый и самый очевидный вопрос: почему на рабочей базе операция длится часы, а на тестовой — секунды? Ответ кроется в активности пользователей.

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

В рабочей базе постоянно идут транзакции: пользователи проводят документы, формируют отчеты, выполняют регламентные задания. Каждая такая операция может устанавливать блокировки на таблицы данных в MS SQL. Процесс включения итогов, столкнувшись с этими блокировками, будет терпеливо ждать их снятия. Если система высоконагруженная, это ожидание может длиться очень долго, что и приводит к многочасовому "зависанию" операции.

На тестовой базе, где нет активных пользователей и фоновых заданий, нет и блокировок. Если за время отключения итогов никаких новых движений не было, система просто меняет внутренний флаг, сообщая, что итоги снова актуальны. Это занимает доли секунды. Если же движения были, их пересчет пройдет быстро, так как ему никто не мешает.

Вывод: Длительное включение итогов в рабочее время — это в первую очередь следствие блокировок со стороны активных сеансов пользователей.

Причина 2: Последствия инцидента — фрагментация индексов и устаревшая статистика

Итак, итоги с горем пополам включились, но система начала "тормозить". Запросы к таблицам остатков и оборотов проблемного регистра стали выполняться в десятки раз дольше. Почему это произошло?

Процедура пересчета итогов — это, по сути, массовая вставка и обновление огромного количества записей в таблицах итогов в СУБД. Такие операции имеют два неприятных побочных эффекта:

  1. Фрагментация индексов. Индексы в базе данных можно сравнить с алфавитным указателем в книге. Когда данные добавляются упорядоченно, указатель работает быстро. Массовые, хаотичные вставки приводят к тому, что страницы индекса "перемешиваются". В результате СУБД тратит гораздо больше времени на поиск нужных данных. Это и есть фрагментация.
  2. Устаревание статистики. Для построения оптимального плана выполнения запроса MS SQL использует статистику о распределении данных в таблицах. После того как в таблицу итогов была добавлена огромная порция новых данных, старая статистика перестает быть актуальной. СУБД, опираясь на неверные данные, строит неэффективные, "медленные" планы запросов.

Именно эти два фактора являются прямой причиной резкого падения производительности после аварийного пересчета итогов.

Причина 3: Глубинная проблема — устаревшая граница рассчитанных итогов

В ходе обсуждения на форуме выяснилась критическая деталь: граница рассчитанных итогов была установлена на 2019 год. Это коренная причина многих проблем с производительностью в данной базе.

Что такое граница итогов? Это точка во времени, до которой в таблицах итогов хранятся рассчитанные наперед обороты и остатки. Когда вы запрашиваете остатки на актуальную дату, система берет ближайший рассчитанный итог и добирает недостающие данные из таблицы движений. Если граница установлена на 31.07.2019, то для получения остатков на сегодняшний день СУБД будет вынуждена каждый раз считывать и агрегировать все движения регистра за несколько лет. Это колоссальная и совершенно избыточная нагрузка.

Такая ситуация возникает на так называемых "незакрывающихся" регистрах, где данные постоянно накапливаются, а регламентная процедура расчета и сдвига границы итогов не выполняется. Это бомба замедленного действия, которая рано или поздно приводит к деградации производительности.

План действий для восстановления производительности

Теперь, когда мы проанализировали причины, давайте составим пошаговый план по исправлению ситуации.

Шаг 1. Срочные меры: Реиндексация и обновление статистики

Это первое, что нужно сделать для "оживления" системы после инцидента. Эти операции должны выполняться непосредственно на стороне MS SQL Server, а не через стандартную реиндексацию в конфигураторе 1С.

Вам или вашему системному администратору необходимо выполнить следующие команды для таблиц проблемного регистра накопления (основной таблицы движений и таблицы итогов):

  1. Реиндексация (REBUILD INDEX): Эта операция полностью перестраивает индексы, устраняя фрагментацию.
  2. Обновление статистики (UPDATE STATISTICS): Эта команда заставляет СУБД пересчитать статистику по таблицам, чтобы она могла строить эффективные планы запросов.

Эти действия должны значительно ускорить выполнение запросов к регистру и вернуть производительность на прежний уровень (или даже улучшить ее).

Шаг 2. Анализ состояния итогов и плановый пересчет

Срочные меры — это хорошо, но они не решают коренную проблему с устаревшей границей. Эту задачу нужно решать планово, в период минимальной нагрузки (ночью или на выходных).

  1. Используйте специализированные инструменты. Для анализа и управления итогами существуют удобные обработки, например, "Управление итогами регистров (ИР)". С их помощью можно без прямого доступа к SQL посмотреть размеры таблиц, текущую границу расчета и выполнить операции по пересчету для конкретного регистра.
  2. Выберите проблемный регистр. Не стоит запускать полный пересчет итогов по всей базе, особенно если вы знаете, что это привело к росту размера базы в прошлом. Сосредоточьтесь на том регистре, который вызвал инцидент.
  3. Выполните пересчет. С помощью выбранной обработки или стандартных средств платформы запустите пересчет итогов для одного регистра. Рекомендуется сначала протестировать операцию на свежей копии базы, чтобы оценить длительность и влияние на размер файла БД. Иногда более быстрым способом является полное удаление таблиц итогов регистра (через ту же обработку ИР) и их последующий пересчет с нуля.
  4. Регулярно сдвигайте границу. После успешного пересчета установите для себя правило: выполнять эту операцию регулярно (например, раз в месяц), чтобы граница итогов всегда была актуальной.

Шаг 3. Стратегическое решение: Ревизия архитектуры

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

← На главную