Дано
Информационная база (УПП) с заброшенными процедурами обслуживания (БД под управлением СУБД MS SQL). Путем анализа выявлены таблицы итогов с количеством записей, многократно превышающим количество, которое должно быть согласно аналитикам прикладной логики.
Причины
1С для оптимизации времени на запись итогов применяет так называемый разделитель. Это позволяет распараллелить процесс записи в конкурентных таблицах при большом количестве обращений.
*Свойство использования разделителя итогов может включаться (Операции – Управление итогами-Вкладка «Установка режима разделения итогов», принятие изменений требует монопольного режима). Поле разделителя итогов «splitter» по умолчанию присутствует во всех таблицах итогов.
Таким образом, фактически в таблице может содержаться 1000 записей, соответствующих 100 уникальным ключам прикладных аналитик, разделенных «разделителем итогов» (от 0 до n).
Как это влияет на производительность? Когда мы запрашиваем «остатки», 1С формирует запрос к таблице итогов и для выдачи сворачивает данные без учета «разделителей». Но при этом СУБД считывает 1000 записей, а выдает 100 (в примере разница не большая, но дает представление). Чем больше разделенных записей, тем выше нагрузка на СУБД.
В рамках штатной процедуры пересчета итогов в таблицах записи сворачиваются. В большинстве случаев проблем с этим не наблюдается. Но при установке новой границы итогов, итоги пересчитываются за конкретный период, а текущие итоги остаются в том состоянии в котором и были, разделенные «разделителями».
Приведем пример из жизни. На первом рисунке (ниже) представлена таблица, которая показывает реальное количество записей в БД. Можно обратить внимание на «текущие итоги», определенные периодом «5999-11-01» - их количество 156 218 467 записей. Сравнить можно с прочими периодами, где количество уникальных ключей прикладной аналитики в итогах составляет примерно 11 000 записей (±1 000), что в десятки тысяч раз меньше.
В следующей табличке приведено количество записей, где «разделитель» отличен от нуля. Мы видим, что количество разделенных записей по периоду текущих итогов составляет примерно 50% (в конкретном случае, может и больше в зависимости от конкурентности). Также можно обратить внимание на последний период (4024-04-01), из общего количества записей 4 533 633, 3 015 292 записи разделенные и могут быть свернуты пересчетом итогов.
Почему так получается? В приведенном примере рассматривается таблица итогов регистра накопления «Учет затрат (регламентированный учет)». Точку актуальности итогов сместили, система рассчитала итоги и зафиксировала. А затем бухгалтер решила перепровести пакетно реализации, требования накладные, отчеты производства за смену и прочее. Поэтому, рекомендуется сдвигать точку актуальности итогов после закрытия периода и завершения всех манипуляций с данными прошлых периодов. По отношению к записям текущих итогов, причина в том, что «период» (с прикладной точки зрения) еще не закрыт, также, как и затраты.
Решение
Как можно исправить ситуацию и «припудрить» состояние итогов? Если технологическое окно позволяет обеспечить монопольный режим, то можно воспользоваться функцией «тестирования и исправления», установив галочки «пересчета итогов». Но в моем случае, технологического окна нет. А указанная функция не позволяет конкретизировать, какие именно таблицы нужно пересчитать. С учетом этих обстоятельств, можно прибегнуть к методам, предусмотренным для регистров накопления. А именно: «ПересчитатьИтоги()». В частном порядке можно пересчитать итоги за конкретный период – «ПересчитатьИтогиЗаПериод(<НачалоПериода>, <КонецПериода>)». Для текущих итогов используется отдельный метод - ПересчитатьТекущиеИтоги(). Важно, использование этих методов проводить в периоды наименьшей загруженности ИБ. Так как при расчете итогов система блокирует таблицы.
Казалось бы, вот и все, решение найдено. И чего ради этого было писать такой талмуд. Но с учетом обстоятельств, проблемы другого характера. Производство работает 20 часов в сутки. Технологическое окно, с использованием монопольного режима допустимо только 2 часа в месяц (!), которое используется исключительно для принятия монопольных изменений. А периоды наименьшей загрузки составляют от 4-х до 6-и часов в сутки. И тут-то приходится выкручиваться «как только можно».
Дальше пойдет «треш», если, дочитав до этого места, у вас не сложилось понимание проблематики, то дальше можно не продолжать.
Итак, основным ограничительным фактором у нас является время, мы должны уложиться в отведенное технологическое окно. Самой длительной операцией в пересчете итогов является удаление существующих записей. По моим подсчетам на практике это занимает до 90% времени выполнения. В моем случае я применил следующий порядок действий:
-
Обслужил основную таблицу регистра (реиндексация и актуализация статистики). Чтобы сократить время на выполнение запроса расчета итогов.
-
Отключил использование текущих итогов – «УстановитьИспользованиеТекущихИтогов(Ложь)»
-
Отключил использование итогов - «УстановитьИспользованиеИтогов(Ложь)»
-
Установил максимальный период рассчитанных итогов на самый ранний период «УстановитьМаксимальныйПериодРассчитанныхИтогов(<Период>)»
-
Далее в SQL очистил таблицу итогов выполнив следующую инструкцию – «TRUNCATE TABLE [sbox_upp_tam].[dbo].[_AccumRgT33795]». Где «sbox_upp_tam» - имя базы, «_AccumRgT33795» - имя таблицы. На все про все, включая данный шаг, времени ушло 5 минут.
-
Затем я включил обратно использование итогов - «УстановитьИспользованиеИтогов(Истина)»
-
Запустил расчет итогов за все периоды, установив максимальный период расчитанных итогов на предпоследний месяц – «УстановитьМаксимальныйПериодРассчитанныхИтогов(<Период>)». Эта процедура длительная, поэтому я расслабился и ушел в режим ожидания. Но «печалька» меня настигла спустя некоторое время. Мало того что до конца оно не рассчиталось, так оно еще пошло в «откат» (в SQL), заблокировав действия по всем базам на сервере. Тут у меня случился легкий «инфаркт ж..пки». Продлилось это состояние порядка 40 минут (имеется в виду «откат», «инфаркт ж..пки» закончился ранее :). И я понял, что так дело не пойдет и нужно менять стратегию. А именно, запускать пересчет по месяцам, постепенно сдвигая максимальный период рассчитанных итогов.
-
Ну и конечно же в финале, установка использования текущих итогов «УстановитьИспользованиеТекущихИтогов(Истина)». Думал я, что после нужно будет запустить пересчет текущих итогов, но поведение системы меня приятно удивило и при включении использования текущих итогов, 1С услужливо их посчитала сама.
Заключение
Решение не самое изящное и не претендует на «решение из коробки». Но возможно кому-то пригодиться этот опыт для решения своих частных случаев. Решение имеет определенные риски в моменте. Но я постарался максимально учесть все возможные обстоятельства, включая возможные ошибки данных, которые возникают при включении и отключении итогов в "немонопольном режиме" (когда работают пользователи). В крайнем случае, если бы на каком-то этапе выполнение прервалось бы, то это повлияло только на производительность без ущерба прикладной логики. В итоге я сэкономил много времени, исчисляемого в сутках, и свел все к паре-тройке часов.
P.S. Данная статья – мой дебют на InfoStart'e. Поэтому прошу сильно тапками не бросаться. Отвечу на уместные вопросы и конструктивную критику.