Как уменьшить размер таблицы итогов регистра накопления, если она в десятки раз больше таблицы движений?

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

Рассмотрим ситуацию, когда таблица итогов регистра накопления становится аномально большой, превышая размер таблицы движений в десятки раз. Эта проблема часто встречается в информационных базах 1С, особенно в крупных конфигурациях, таких как УПП, и может значительно влиять на производительность системы. Мы выясним причины такого разрастания и предложим комплексные решения, которые помогут оптимизировать работу ваших регистров накопления. Для наглядного выявления наиболее «тяжёлых» таблиц и оценки распределения дискового пространства подойдёт инструмент для анализа карты объёмов базы 1С.

Что такое регистры накопления и почему разрастаются их таблицы итогов?

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

  1. Таблица движений (например, dbo._AccumRg28133 для регистра "Расходы при УСН") хранит каждую отдельную запись о приходе или расходе по регистру. Это "первичные" данные.
  2. Таблица итогов (например, dbo._AccumRgT28152) содержит агрегированные данные, необходимые для быстрого получения остатков или оборотов на определенный момент времени. Эти данные, как правило, рассчитываются с определенной периодичностью (обычно месяц) и хранят значения на начало каждого периода по всем уникальным комбинациям измерений.

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

Основные причины аномального роста таблицы итогов

Мы проанализируем две основные причины, которые чаще всего приводят к данной проблеме, и рассмотрим способы их устранения.

1. Влияние режима "Разделение итогов"

Одной из наиболее частых и значительных причин разрастания таблицы итогов является включенный режим "Разделение итогов" для регистра накопления.

Что такое "Разделение итогов"?

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

Как это приводит к росту таблицы?

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

Решение: Отключение режима "Разделение итогов" и пересчет

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

  1. Проверяем текущее состояние: Для начала убедимся, что режим "Разделение итогов" включен для проблемного регистра. Это можно сделать через стандартную обработку "Управление итогами", которая доступна в режиме 1С:Предприятие через "Функции для технического специалиста". Откроем эту обработку, найдем наш регистр (в исходной теме это "Расходы при УСН") и посмотрим на состояние опции "Разделение итогов".
  2. Отключаем режим: Если опция "Разделение итогов" включена, мы отключаем ее для данного регистра. После изменения настройки система предложит выполнить реструктуризацию таблицы, с чем мы соглашаемся. Этот шаг является критически важным, поскольку именно он позволяет физически объединить "разделенные" записи.
  3. Пересчитываем итоги: После отключения режима и реструктуризации обязательно выполним полный пересчет итогов для данного регистра. Это можно сделать через ту же обработку "Управление итогами" или с помощью стандартных средств платформы (например, в режиме конфигуратора: "Администрирование" -> "Тестирование и исправление" -> "Пересчет итогов" с указанием проблемного регистра). Важно: убедимся, что пересчет выполнен полностью, и внимательно отслеживаем размер таблицы итогов.

Как показал опыт из обсуждения на форуме, отключение "Разделения итогов" с последующей реструктуризацией и пересчетом дало очень значительный результат: размер таблицы сократился со 164 миллионов записей и 51 ГБ до 5 миллионов записей и 1.6 ГБ.

2. "Висящие" остатки и старые движения

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

Как это происходит?

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

Это особенно актуально для регистров, где движения могут быть "односторонними" (например, только приход без расхода, или наоборот), или когда используются некорректные даты (например, "нулевые" даты 01.01.0001) в измерениях, что может уводить остатки в глубокое прошлое.

Как выявить такие движения?

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

Пример кода для поиска минимальной и максимальной даты движений по регистрам накопления:


&НаСервере
Процедура ПоказатьНаСервере()
    // Создаем таблицу для хранения минимальных дат движений
    ТаблицаМинимальныхДат = Новый ТаблицаЗначений;
    ТаблицаМинимальныхДат.Колонки.Добавить("ИмяРегистра");
    ТаблицаМинимальныхДат.Колонки.Добавить("МинимальнаяДата", Новый ОписаниеТипов("Дата"));
    ТаблицаМинимальныхДат.Колонки.Добавить("МинимальнаяДатаСтрокой");

    // Создаем таблицу для хранения максимальных дат движений
    ТаблицаМаксимальныхДат = Новый ТаблицаЗначений;
    ТаблицаМаксимальныхДат.Колонки.Добавить("ИмяРегистра");
    ТаблицаМаксимальныхДат.Колонки.Добавить("МаксимальнаяДата", Новый ОписаниеТипов("Дата"));
    ТаблицаМаксимальныхДат.Колонки.Добавить("МаксимальнаяДатаСтрокой");

    // Вызываем вспомогательную процедуру для заполнения таблиц
    ПоказатьТаблицуНаСервере(ТаблицаМинимальныхДат, "МинимальнаяДата", Ложь); // Ищем минимальные даты
    ПоказатьТаблицуНаСервере(ТаблицаМаксимальныхДат, "МаксимальнаяДата", Истина); // Ищем максимальные даты
КонецПроцедуры

&НаСервере
Процедура ПоказатьТаблицуНаСервере(Таблица, ИмяКолонки, ПоУбыванию)
    // Определяем суффикс для сортировки в запросе
    СуффиксСортировки = ?(ПоУбыванию, " Убыв", "");
    Таблица.Очистить(); // Очищаем таблицу перед заполнением

    // Перебираем все регистры накопления в метаданных
    Для Каждого Метаданное Из Метаданные.РегистрыНакопления Цикл
        Запрос = Новый Запрос;
        Запрос.Текст =
        "ВЫБРАТЬ ПЕРВЫЕ 1
        |    Регистр.Период КАК Период
        |ИЗ
        |    РегистрНакопления." + Метаданное.Имя + " КАК Регистр
        |
        |УПОРЯДОЧИТЬ ПО
        |    Период" + СуффиксСортировки; // Сортируем по Периоду для получения первой (минимальной) или последней (максимальной) даты
        Выборка = Запрос.Выполнить().Выбрать();

        // Если в регистре есть движения
        Если Выборка.Следующий() Тогда
            НоваяСтрока = Таблица.Добавить();
            НоваяСтрока.ИмяРегистра = Метаданное.Синоним; // Синоним регистра для удобства
            НоваяСтрока[ИмяКолонки] = Выборка.Период; // Сама дата
            НоваяСтрока[ИмяКолонки + "Строкой"] = Выборка.Период; // Дата в строковом представлении
        КонецЕсли;
    КонецЦикла;
    // Сортируем итоговую таблицу
    Таблица.Сортировать(ИмяКолонки + СуффиксСортировки);
КонецПроцедуры

Решение:

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

Дополнительная проверка на "нулевые записи":

Иногда причиной большого объема могут быть записи в таблице итогов, у которых все ресурсы равны нулю. Эти записи также должны сворачиваться при пересчете итогов, но иногда остаются. Их можно попытаться найти прямым запросом к СУБД (с большой осторожностью и только для анализа, не для изменения данных!):


SELECT count(*)
FROM [dbo].[_AccumRgT28152] -- Замените на фактическое имя таблицы итогов вашего регистра
WHERE [_Fld28147] = 0 AND [_Fld28148] = 0 AND [_Fld28149] = 0; -- Замените поля на фактические ресурсы вашего регистра

В этом запросе _Fld28147, _Fld28148, _Fld28149 — это примеры имен полей ресурсов регистра в физической таблице базы данных. Аккуратно определите фактические имена полей ресурсов для вашего регистра, используя, например, функцию ПолучитьСтруктуруХраненияБазыДанных(). Для быстрого просмотра соответствия объектов метаданных и физических таблиц СУБД можно использовать обработку для анализа структуры хранения базы данных.

Общие рекомендации по оптимизации регистров накопления

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

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

Особенности регистра "Расходы при УСН"

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

Заключение:

Разрастание таблицы итогов регистра накопления – это серьезная проблема производительности, но, как мы выяснили, она решаема. Основными виновниками могут быть режим "Разделение итогов" и "висящие" остатки по старым или некорректным движениям. Комплексный подход, включающий отключение разделения итогов, исправление данных, управление параметрами итогов через обработку "Управление итогами", а также регулярное обслуживание базы данных с помощью ТИИ и свертки, поможет поддерживать вашу систему 1С в оптимальном состоянии. Всегда помните о необходимости резервного копирования перед внесением серьезных изменений.

← На главную