Почему сильно разрастается база 1С и как уменьшить размер файла данных MS SQL?

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

Типичная ситуация при администрировании клиент-серверных баз 1С: информационная база стабильно росла на 1 Гб в месяц, но после очередного обновления конфигурации файл базы данных (.mdf) внезапно увеличился на 10–15 Гб или более. При этом фактический объем первичных документов практически не изменился.

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

Архитектурная причина: почему таблицы итогов раздувают размер базы

В платформе 1С для регистров накопления остатков создаются две основные физические таблицы на уровне СУБД:

  1. Таблица движений (записей регистра) — содержит все строки приходов и расходов, проведенных документами.
  2. Таблица итогов (имеет суффикс _AccumRgT) — хранит рассчитанные остатки. В ней находятся актуальные итоги (на системную дату 01.11.3999), а также промежуточные срезы на начало каждого месяца вплоть до даты рассчитанных итогов.

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

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

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

Шаг 1. Диагностика размеров таблиц в базе данных

Прежде чем выполнять любые действия, необходимо точно определить, какие именно таблицы занимают основной объем. Для этого выполним анализ физического распределения дискового пространства в MS SQL Management Studio или с помощью специализированных отчетов 1С.

Выясним причину с помощью системного отчета в MS SQL Server Management Studio (SSMS):

  1. Открываем SSMS и подключаемся к серверу баз данных.
  2. Нажимаем правой кнопкой мыши на исследуемую базу данных.
  3. Переходим в меню: Reports (Отчеты) -> Standard Reports (Стандартные отчеты) -> Disk Usage by Top Tables (Использование диска основными таблицами).

В отчете смотрим на соотношение объема таблицы движений (_AccumRg) и таблицы итогов (_AccumRgT). Если таблица итогов по регистру партий (или остатков товаров) в разы превышает размер таблицы самих записей, это однозначно указывает на наличие незакрытых остатков за длительный период.

Также проверяем наличие временных служебных таблиц. При сбоях или отмене реструктуризации во время обновления в базе могут остаться брошенные таблицы с префиксами _1Cv8_tmp_ или суффиксами _NG, занимающие гигабайты пространства.

Шаг 2. Выявление и устранение причин незакрытия регистров

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

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

Разберем способы устранения проблемы:

Вариант А. Корректировка зависших остатков (рекомендуемый без перепроведения прошлых лет)

Если база ведется много лет и перепроведение документов за прошлые периоды недопустимо, оптимальным решением является точечное закрытие зависших хвостов с помощью документа КорректировкаЗаписейРегистров:

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

Вариант Б. Свертка информационной базы

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

Шаг 3. Управление итогами на программном уровне

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

Сдвиг границы расчета итогов назад позволяет платформе не формировать ежемесячные срезы за ненужные периоды. Для этого используется метод:


РегистрыНакопления.ПартииТоваровНаСкладах.УстановитьПериодРассчитанныхИтогов(ДатаНачалаПериода);

Если регистр полностью устарел и расчет остатков по нему больше не требуется, можно отключить использование итогов:

РегистрыНакопления.УстаревшийРегистр.УстановитьИспользованиеИтогов(Ложь);

Шаг 4. Физическое сжатие базы данных и обслуживание MS SQL

После того как данные в регистрах выровнены и лишние итоги удалены, физический размер файла .mdf на диске автоматически не уменьшится — MS SQL оставляет освобожденное место внутри файла под будущие операции. Для возврата места на диск выполним комплекс процедур обслуживания.

Разберем по шагам правильный порядок действий:

  1. Тестирование и исправление: запускаем в конфигураторе 1С полное «Тестирование и исправление» с установленными флагами «Пересчет итогов», «Сжатие таблиц» и «Реиндексация таблиц».
  2. Сжатие файла данных (Shrink): в среде MS SQL Server освобождаем место. Использование команды с параметром TRUNCATEONLY освобождает только свободное место в конце файла:
    
    USE [ИмяБазыДанных]
    GO
    DBCC SHRINKFILE (N'ИмяФайлаДанных', 0, TRUNCATEONLY);
    GO
    
    Если свободное место находится внутри файла, выполняем сжатие с перемещением страниц данных:
    
    USE [ИмяБазыДанных]
    GO
    DBCC SHRINKFILE (N'ИмяФайлаДанных', ЖелаемыйРазмерВМБ);
    GO
    
  3. Перестроение индексов (Rebuild Index): процедура сжатия файла данных приводит к сильнейшей фрагментации индексов (до 95–99%). Поэтому сразу после сжатия обязательно выполняем перестроение индексов:
    
    USE [ИмяБазыДанных]
    GO
    EXEC sp_MSforeachtable @command1="ALTER INDEX ALL ON ? REBUILD";
    GO
    
  4. Обновление статистик:
    
    USE [ИмяБазыДанных]
    GO
    EXEC sp_updatestats;
    GO
    

Альтернативный способ очистки через выгрузку в .dt:

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

← На главную