При разработке сложных систем на платформе 1С:Предприятие часто возникает задача расширения типовой аналитики. Например, когда необходимо привязать специфические данные из множества различных документов к записям регистра бухгалтерии или накопления. Одним из первых порывов разработчика часто становится использование составного типа данных в измерениях регистра. В данной статье мы разберем, почему это решение может стать «миной замедленного действия», проанализируем влияние на производительность СУБД и рассмотрим наиболее эффективные альтернативные подходы.
Рассмотрим ситуацию: у нас есть около 20 видов документов, в каждом из которых присутствует табличная часть с уникальным идентификатором (GUID) и значениями из Плана видов характеристик (ПВХ). Задача состоит в том, чтобы связать эти данные с проводками в регистре бухгалтерии. Автор темы предлагает создать в регистре новое измерение или реквизит составного типа, чтобы хранить там связь.
Разберем основные аргументы против такого подхода. Основная проблема заключается не в самом факте наличия составного типа, а в том, как платформа 1С и СУБД взаимодействуют с такими данными. Когда мы создаем измерение составного типа, включающее 20 видов документов, платформа на уровне базы данных создает не одну колонку, а целую группу полей для хранения ссылки, типа и логических значений. Это приводит к значительному «раздуванию» таблиц и, что более важно, индексов.
Основные риски использования составных типов:
Измерение.Наименование) заставляет платформу генерировать SQL-запрос с LEFT JOIN ко всем таблицам, входящим в состав типа. Если типов 20, вы получите 20 соединений на ровном месте, что может парализовать работу оптимизатора запросов SQL.Наиболее правильным архитектурным решением в данной ситуации является создание вспомогательного Регистра сведений (РС). Рассмотрим этот вариант подробнее. Вместо того чтобы «мучить» типовой регистр бухгалтерии, мы создаем непериодический регистр сведений, который будет хранить связь между GUID и необходимыми нам значениями ПВХ.
Преимущества этого метода:
Проанализируем пример кода, который может использоваться для записи данных в такой регистр при проведении документа:
Процедура ПриПроведении(Отказ, РежимПроведения)
// Создаем набор записей нашего вспомогательного регистра
НаборЗаписей = РегистрыСведений.ДополнительнаяАналитикаПоGUID.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Регистратор.Установить(Ссылка);
Для Каждого СтрокаТЧ Из ТабличнаяЧасть Цикл
НоваяЗапись = НаборЗаписей.Добавить();
НоваяЗапись.Регистратор = Ссылка;
НоваяЗапись.GUID_Связи = СтрокаТЧ.ГУИД;
НоваяЗапись.ТипПВХ = СтрокаТЧ.ТипПВХ;
НоваяЗапись.ЗначениеПВХ = СтрокаТЧ.ЗначениеПВХ;
КонецЦикла;
НаборЗаписей.Записать();
КонецПроцедуры
В этом случае, если нам нужно построить отчет, объединяющий данные проводок и нашей аналитики, мы используем левое соединение в запросе. Это работает гораздо предсказуемее, чем составной тип в измерении.
Рассмотрим ситуацию, когда разработчик не хочет дублировать данные в регистр сведений и планирует «вытаскивать» аналитику напрямую из документов в момент построения отчета. Как правильно заметили участники обсуждения, если видов документов много, запрос превратится в нагромождение ОБЪЕДИНИТЬ ВСЕ или бесконечные джойны.
Почему это плохо:
Если вы все же решите идти по этому пути, проанализируем структуру запроса, которой стоит избегать:
ВЫБРАТЬ
Хозрасчетный.Счет,
Хозрасчетный.Сумма,
ВЫБОР
КОГДА Хозрасчетный.Регистратор ССЫЛКА Документ.РеализацияТоваровУслуг
ТОГДА Хозрасчетный.Регистратор.ТабличнаяЧасть.Значение
КОГДА Хозрасчетный.Регистратор ССЫЛКА Документ.ПоступлениеТоваровУслуг
ТОГДА Хозрасчетный.Регистратор.ТабличнаяЧасть.Значение
// И так далее для 20 документов...
КОНЕЦ КАК ДопАналитика
ИЗ
РегистрБухгалтерии.Хозрасчетный КАК Хозрасчетный
Такой запрос будет крайне неэффективным. Если данных много, время выполнения будет измеряться минутами.
Выясним причину, по которой работа с GUID как строкой является плохой практикой. В 1С тип УникальныйИдентификатор на уровне СУБД хранится как binary(16). Это компактный и быстро индексируемый тип. Если же разработчик решает хранить GUID как строку (String 36), размер индекса увеличивается в разы, а сравнение строк в SQL работает значительно медленнее, чем сравнение бинарных данных.
Рекомендации по работе с идентификаторами:
Разберем еще один продвинутый способ организации аналитики — через механизм характеристик. Вместо прямого указания составного типа в измерении, мы можем указать тип Характеристика.[ИмяПВХ].
Проанализируем ситуацию: ПВХ позволяет «инкапсулировать» составной тип внутри себя. Платформа 1С оптимизирует работу с характеристиками. Если в отчете пользователю нужно видеть разные типы данных в одной колонке, ПВХ — это стандартный и наиболее чистый способ реализации с точки зрения архитектуры метаданных. Это позволяет избежать изменения структуры таблиц регистра при добавлении новых типов данных в ПВХ.
Подводя итог нашему анализу, можно сформулировать следующие правила для проектирования регистров с дополнительной аналитикой:
Рассмотрим финальный пример правильной организации запроса при использовании вспомогательного регистра сведений:
ВЫБРАТЬ
Проводки.Период,
Проводки.Регистратор,
Проводки.Сумма,
Аналитика.ЗначениеПВХ КАК ДополнительныйПараметр
ИЗ
РегистрБухгалтерии.Хозрасчетный КАК Проводки
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ДополнительнаяАналитика КАК Аналитика
ПО Проводки.Регистратор = Аналитика.Регистратор
И Проводки.НомерСтроки = Аналитика.НомерСтрокиСвязи
ГДЕ
Проводки.Период МЕЖДУ &Начало И &Конец
Такой подход обеспечивает максимальную производительность, масштабируемость системы и чистоту типовой конфигурации, что значительно облегчит ее поддержку в будущем.