В сообществе разработчиков 1С давно ведется спор о том, какой объект метаданных использовать для хранения больших массивов информации — справочник или независимый регистр сведений. Существует устойчивый миф, пришедший из старых обучающих курсов, что при объеме данных свыше миллиона записей справочник неизбежно «зависнет», поэтому для хранения плоских списков нужно использовать только регистры. Но так ли это на самом деле?
В этой статье мы подробно разберем практический эксперимент, проведенный на базе СУБД PostgreSQL с использованием современной платформы «1С:Предприятие», сравним показатели производительности справочника и регистра сведений при объеме в 4 миллиона строк и проанализируем глубинную внутреннюю кухню платформы 1С и СУБД.
Проанализируем параметры тестового стенда, на котором проводилось сравнение:
ХранилищеЗначения с большим объемом данных для имитации реальной нагрузки на дисковую подсистему.Давайте посмотрим на результаты замеров производительности в ключевых операциях:
Справочник ++). Навигация и прокрутка строк справочника выполняются плавнее.Справочник ++).Справочник ++++++++). Поиск по регистру сведений привел к длительному ожиданию, тогда как справочник выдал результаты практически мгновенно.Выясним причины такого поведения системы и разберем физические механизмы хранения данных.
Разберем подробнее, как СУБД физически располагает данные на диске и почему запись в справочник оказывается быстрее. Для анализа объема дискового пространства и размера таблиц СУБД пригодится обработка для оценки размера таблиц и индексов в разрезе метаданных 1С.
Для каждого типа объекта СУБД создает кластерный (физический) индекс:
Ссылка (в СУБД это поле _IDRRef), которое хранит уникальный 16-байтный идентификатор (GUID). При генерации новых элементов платформа использует оптимизированные, последовательно возрастающие UUID (Sequential UUID). Это позволяет СУБД выполнять запись максимально «плоско» и последовательно. СУБД просто дописывает новые строки в конец таблицы без необходимости перетасовки старых данных на диске. Проверка уникальности кода или наименования выполняется по отдельным некластерным индексам, что не оказывает критического влияния на общую скорость вставки.Для ускорения массовой записи в регистр сведений можно использовать свойство обмена данными, отключающее транзакционные проверки:
НаборЗаписей = РегистрыСведений.ТестовыйРегистр.СоздатьНаборЗаписей();
НаборЗаписей.ОбменДанными.Загрузка = Истина;
// Заполнение набора записей данными
НаборЗаписей.Записать();
Превосходство справочника при перемещении по списку напрямую связано с тем, как динамический список запрашивает данные у СУБД порциями (страницами). Проанализируем разницу в SQL-запросах, которые генерирует платформа 1С для СУБД:
Ссылка. Чтобы выбрать следующую порцию данных при прокрутке списка вниз, СУБД выполняет быстрый и лаконичный запрос, условие выборки в котором выглядит как WHERE Ссылка > ПоследняяПолученнаяСсылка. Такой запрос идеально попадает в индекс и отрабатывает мгновенно.WHERE (Измерение1 >= Последнее1) И (Измерение2 > Последнее2).... Подобные конструкции создают колоссальную нагрузку на оптимизатор запросов СУБД, снижая общую отзывчивость интерфейса при работе с многомиллионными регистрами.Фантастическая разница в скорости глобального поиска (Справочник ++++++++) объясняется использованием механизмов полнотекстового поиска (ПТС):
LIKE '%СтрокаПоиска%'. На таблице в 4 миллиона записей такой запрос гарантированно отправляет интерфейс системы в глубокое зависание.В ходе практической работы программисты нередко сталкиваются с ситуацией, когда подчиненный справочник при больших объемах данных начинает сильно замедлять работу системы, особенно в транзакциях записи. Почему так происходит?
Когда мы связываем один справочник с другим через свойство «Владелец», платформа 1С накладывает жесткий контроль ссылочной целостности. При записи элемента подчиненного справочника платформа под капотом выполняет неявные запросы для проверки физического существования владельца и накладывает дополнительные блокировки на таблицы СУБД. В регистрах сведений такой автоматической проверки «из коробки» нет. Регистр просто хранит ссылки в измерениях как плоские значения данных. Ответственность за контроль целостности в РС полностью лежит на разработчике, что делает запись в регистры более «легковесной» в сложных реляционных схемах при отсутствии жестких требований к ссылочной структуре.
Если в старых версиях платформы (включая тестовую 8.3.13) регистры сведений значительно уступали справочникам в сценариях частой и конкурентной перезаписи, то начиная с версии платформы 8.3.25 фирма 1С кардинально обновила механизмы работы с независимыми регистрами сведений. Переход на современные версии платформы и плановое обслуживание инфраструктуры обеспечивает Обновлятор 1С для автоматического архивирования и тестирования баз.
Рассмотрим ключевые нововведения, которые существенно повысили скорость работы с регистрами сведений:
Раньше метод Записать() для набора записей регистра работал по принципу полного замещения данных по отбору (сначала выполнялась операция удаления старых записей СУБД, затем вставка новых). Это приводило к избыточным блокировкам и фрагментации индексов. Теперь разработчикам доступно системное перечисление РежимЗамещения со следующими режимами:
Посмотрим на пример использования нового режима записи:
НаборЗаписей = РегистрыСведений.ИсторияСтатусов.СоздатьНаборЗаписей();
// Заполнение ключевых измерений и ресурсов
НоваяСтрока = НаборЗаписей.Добавить();
НоваяСтрока.Документ = СсылкаНаДокумент;
НоваяСтрока.Статус = Перечисления.СтатусыДокументов.Проведен;
// Используем новые возможности платформы 8.3.25
НаборЗаписей.Записать(Истина, РежимЗамещения.Слияние);
Ранее при изменении состава типов в измерениях РС платформа не удаляла неактуальные данные, а записывала на их место значение Неопределено, что приводило к раздуванию индексов. Начиная с версии 8.3.25, свойство «Режим сокращения типа» позволяет физически отсекать устаревшие строки на уровне СУБД в процессе реструктуризации, сохраняя высокую скорость выборки по регистру.
Проанализировав результаты практических тестов и внутреннее устройство платформы, сформулируем четкие правила для проектирования архитектуры больших информационных систем:
Таким образом, утверждение, что справочники не подходят для хранения миллионов записей — не более чем миф. При правильном проектировании индексов и использовании встроенных механизмов платформы справочники показывают превосходную производительность на больших объемах данных.