Почему резко вырос размер таблицы в MS SQL Server при работе с 1С и как это исправить?

Системный администратор 1С v8.3 (Обычные формы)
← На главную

Ситуация, когда одна таблица в базе данных MS SQL Server начинает неконтролируемо расти, достигая гигантских размеров при относительно небольшом количестве записей, является классической проблемой при эксплуатации высоконагруженных систем на платформе 1С:Предприятие. Особенно часто это затрагивает табличные части документов (например, Товары), которые подвергаются частому перестроению. Разберем подробно, почему это происходит и как вернуть базе нормальный объем.

Анализ проблемы: почему объем данных не соответствует количеству строк

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

  1. Механизм Ghost Cleanup: При удалении строк в MS SQL Server они не стираются физически сразу. Они помечаются как "фантомные" (ghost records). Специальный фоновый процесс должен их вычищать. Если в системе есть долгая открытая транзакция (например, кто-то с утра открыл отчет или завис сеанс), процесс очистки блокируется, и таблица начинает "пухнуть" при каждой перезаписи документа.
  2. Разбиение страниц (Page Splits): Если в таблице настроены индексы, которые не позволяют вставлять данные строго в конец (например, из-за особенностей GUID или состава индексов 1С), SQL Server вынужден разрывать существующие страницы данных, чтобы вставить новые строки. Это создает пустоты, из-за которых таблица занимает в 2-3 раза больше места, чем нужно.
  3. Типы данных LOB: Наличие полей неограниченной длины (строки, хранилища значений) заставляет SQL Server хранить данные на отдельных страницах. При частом обновлении эти страницы крайне неохотно отдают место обратно операционной системе.

Решение 1: Пересоздание таблицы (метод TRUNCATE)

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

Выполним последовательность действий в SQL Server Management Studio (SSMS):


-- 1. Создаем временную копию данных во временную таблицу
SELECT * INTO _Document635_VT19248_TEMP FROM _Document635_VT19248;

-- 2. Полностью очищаем исходную таблицу (это сбросит счетчики и освободит страницы)
TRUNCATE TABLE _Document635_VT19248;

-- 3. Возвращаем данные обратно с использованием блокировки таблицы для ускорения
INSERT INTO _Document635_VT19248 WITH (TABLOCK) SELECT * FROM _Document635_VT19248_TEMP;

-- 4. Удаляем временную таблицу
DROP TABLE _Document635_VT19248_TEMP;

Важно: Данный метод эффективен, если таблица не имеет сложных внешних ключей (foreign keys), что характерно для типовых структур 1С. Однако помните, что это лишь временное решение симптома, а не лечение причины.

Решение 2: Оптимизация через обслуживание индексов и сжатие

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

Во-первых, попробуем выполнить реиндексацию. В отличие от дефрагментации, REBUILD индекса пересоздает его заново, что эффективно схлопывает пустые страницы:

ALTER INDEX ALL ON _Document635_VT19248 REBUILD;

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

DBCC SHRINKDATABASE (N'Имя_Вашей_Базы');

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

Решение 3: Поиск первопричины через Технологический журнал

Чтобы понять, какой именно процесс в 1С "раздувает" таблицу, проанализируем активность платформы. Выясним, кто и какими порциями пишет данные. Для этого настроим Технологический журнал (ТЖ) 1С. Рассмотрим пример конфигурационного файла logcfg.xml, который отследит обращения к нашей проблемной таблице:


<config xmlns="http://v8.1c.ru/v8/tech-log">
  <log location="C:\Logs\SQL_Growth" history="24">
    <event>
      <eq property="Name" value="DBMSSQL"/>
      <like property="Sql" value="%_Document635_VT19248%"/>
    </event>
    <property name="All"/>
  </log>
</config>

Проанализируем полученный лог. Мы увидим все запросы INSERT и DELETE. Если в логах зафиксированы тысячи записей в секунду по одним и тем же документам, значит, проблема в программном коде 1С. Часто это происходит из-за того, что в транзакции записи документа выполняется какая-то проверка, которая снова инициирует запись того же самого объекта.

Рекомендации по предотвращению роста

Для предотвращения подобных ситуаций в будущем, проанализируем и внедрим следующие правила обслуживания базы данных:

Подводя итог, отметим: если таблица _Document635_VT19248 выросла до 10Гб при миллионе строк — это явная аномалия хранения. Используйте метод с временной таблицей для быстрой очистки, но обязательно настройте Технологический журнал, чтобы найти "виновный" процесс в коде 1С, который провоцирует постоянную перезапись данных.

← На главную