Долгое время разработчики на платформе «1С:Предприятие 8» были ограничены жестким лимитом: количество строк в любой табличной части (ТЧ) документа или справочника не могло превышать 99 999. Это ограничение было связано с форматом хранения номера строки в базе данных. С выходом версии 8.3.27 ситуация кардинально изменилась. Обзор платформы 1С:Предприятие 8.3.27 показывает, что теперь система позволяет хранить до 1 000 000 000 (одного миллиарда) строк в одной табличной части. В этой статье мы подробно разберем, как активировать эту возможность, где она действительно необходима и какие опасности подстерегают разработчика при работе с «тяжелыми» объектами.
Проанализируем, как именно платформа реализует это расширение. В метаданных табличных частей появилось новое свойство — Длина номера строки (LineNumberLength). По умолчанию оно равно 5, что соответствует старому лимиту (99 999 строк). Для того чтобы снять ограничение, нам необходимо вручную изменить это значение.
Рассмотрим пошагово, что происходит при изменении этого параметра:
Важно понимать: при увеличении этого значения платформа выполняет реструктуризацию базы данных. Тип колонки _LineNo в соответствующей таблице СУБД (Microsoft SQL Server, PostgreSQL и др.) меняется с numeric(5) на более емкий, например numeric(10). При развертывании системы, особенно если используется концепция защищенной IT инфраструктуры на базе Astra Linux и PostgreSQL, важно заранее учитывать подобные изменения в схеме данных. Изучая работу СУБД под капотом 1С, используя анализ SQL сервера глазами 1С-ника, можно заметить, что изменение типа этой колонки напрямую влияет на производительность индексов и длительность транзакций при записи гигантских объектов.
Выясним, кому и зачем может понадобиться такое огромное количество строк. Многие разработчики справедливо замечают, что для «человеческого» ввода 100 000 строк — это уже запредел. Однако современные системы автоматизации давно вышли за рамки ручного ввода данных. Для обеспечения стабильности в таких условиях важно внедрять стандарты разработки компонентов для быстродействия больших баз данных. Рассмотрим ситуации, где миллиард строк оправдан:
Проанализируем ситуацию с точки зрения производительности. То, что база данных может хранить миллиард строк, не означает, что сервер 1С может легко ими манипулировать. Основная проблема заключается в объектной модели платформы. Перед внедрением подобных решений на продуктив рекомендуется провести нагрузочный тест для базы данных 1С, чтобы понять, как система справится с возросшей нагрузкой.
Когда мы вызываем метод ПолучитьОбъект(), платформа считывает в оперативную память сервера (в рабочий процесс rphost) весь объект целиком, включая все его табличные части. Чтобы не «уронить» rphost и грамотно оптимизировать оперативную память, крайне важно понимать последствия выполнения следующего кода:
// Опасный код для объекта с гигантской ТЧ
СсылкаНаДок = Документы.РеализацияТоваровУслуг.НайтиПоНомеру("001");
ОбъектДок = СсылкаНаДок.ПолучитьОбъект(); // Здесь может произойти Memory Overflow
Для Каждого СтрокаТЧ Из ОбъектДок.Товары Цикл
// Какая-то обработка
КонецЦикла;
Что происходит в этот момент? Каждая строка ТЧ в памяти занимает значительно больше места, чем в сжатом виде в БД. Документ с 1 000 000 строк может потребовать несколько гигабайт оперативной памяти. Если таких объектов одновременно будет считано несколько, рабочий процесс будет принудительно завершен операционной системой или самой платформой из-за превышения лимитов памяти.
Разберем, как избежать проблем с памятью при работе с большими табличными частями. Если вам нужно просто прочитать данные, никогда не используйте ПолучитьОбъект(). Статья про использование запросов против объектной модели при работе с большими данными наглядно демонстрирует преимущества этого подхода. Также, если вы используете механизмы платформы 8.3.25 и выше, обратите внимание на новые возможности работы с временными таблицами, такими как добавление данных в существующую временную таблицу, что может быть эффективно при подготовке данных для ТЧ.
Посмотрим на пример правильного чтения данных:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| РеализацияТоваровУслугТовары.Номенклатура,
| РеализацияТоваровУслугТовары.Количество
|ИЗ
| Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТоваровУслугТовары
|ГДЕ
| РеализацияТоваровУслугТовары.Ссылка = &Ссылка";
Запрос.УстановитьПараметр("Ссылка", НужнаяСсылка);
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
// Обрабатываем данные порциями, не загружая весь объект в память
КонецЦикла;
Если же вам необходимо записать большое количество строк, старайтесь формировать объект программно и записывать его один раз, избегая лишних чтений. При записи объектов с огромными ТЧ также следует учитывать длительность транзакций и возможные блокировки таблиц СУБД. При записи 1 миллиона строк транзакция может длиться десятки секунд, блокируя смежные таблицы индексов.
Разберем, как миллиард строк будет выглядеть для пользователя. К счастью, в управляемых формах платформа давно использует механизм динамического считывания данных для таблиц, связанных с ТЧ. Это означает, что если пользователь просто открыл форму документа, платформа не качает все миллион строк на клиент. Она запрашивает только те данные, которые видны на экране (например, первые 40-50 строк).
Однако следует помнить о следующих моментах:
Выясним причину, по которой раньше вместо ТЧ использовали Регистры Сведений (РС). РС позволяют работать с данными порционно через запросы или наборы записей с фильтрами по измерениям. В некоторых случаях для оптимизации старых баз может применяться универсальное сжатие базы за счет очистки табличных частей в закрытых периодах, что подчеркивает ресурсоемкость хранения данных именно в ТЧ.
Когда использовать ТЧ (даже большую):
Когда лучше остаться на Регистре Сведений:
Подводя итог нашему анализу, можно сказать, что увеличение лимита строк до миллиарда — это мощный инструмент для систем уровня Enterprise. Мы рассмотрели, что это нововведение избавляет от необходимости проектировать сложные «костыли» с дроблением объектов. Однако ответственность за производительность теперь полностью ложится на плечи разработчика.
Помните: возможность платформы записать миллиард строк не означает, что ваша конфигурация готова к их обработке. Проанализируйте каждый вызов ПолучитьОбъект() и убедитесь, что ваш сервер обеспечен достаточным объемом оперативной памяти для таких операций. Используйте запросы для чтения и механизмы фонового выполнения для записи тяжелых документов, чтобы не блокировать работу пользователей в интерактивном режиме.