Работа с большими массивами данных (от 2 млн записей и выше) в системе 1С требует особого внимания к архитектуре регистров и качеству написания запросов. Часто разработчики сталкиваются с ситуацией, когда отчет, использующий механизм компоновки данных (СКД), начинает выполняться недопустимо долго — от 10 минут до нескольких часов, «подвешивая» рабочий процесс сервера rphost. Рассмотрим детально, почему это происходит и как довести время формирования отчета до целевых показателей в 30 секунд.
Прежде всего, проанализируем выбор типа регистра накопления. В обсуждаемой ситуации часто возникает путаница между регистрами остатков и оборотов. Если для анализа продаж используется регистр типа Остатки, то при обращении к виртуальной таблице Обороты система не сможет использовать предварительно рассчитанные таблицы итогов оборотов. Вместо этого платформа будет вынуждена сканировать основную таблицу движений регистра, что при 2 миллионах записей неизбежно приведет к деградации производительности.
Важный момент: если ваша задача — анализ оборотных показателей (продажи, закупки, затраты), используйте регистр накопления с видом Обороты. Это позволит системе задействовать механизм итогов, который хранит уже агрегированные данные по месяцам, значительно сокращая объем считываемой информации.
Одной из самых распространенных ошибок является разыменование полей (обращение через точку к реквизитам ссылочных типов) в итоговой выборке запроса. Например, конструкция ПродажиОбороты.Покупатель.ИНН заставляет SQL-сервер выполнять неявное левое соединение с таблицей справочника Контрагенты для каждой строки результата. Если в результате запроса 200 000 строк, количество таких соединений становится критическим.
Рассмотрим, как правильно переписать запрос, используя явные соединения. Вместо обращения через точку, выполним ЛЕВОЕ СОЕДИНЕНИЕ:
ВЫБРАТЬ
ПродажиОбороты.Продавец КАК Продавец,
ПродажиОбороты.Покупатель КАК Покупатель,
ЕСТЬNULL(СпрКонтрагенты.ИНН, "") КАК ПокупательИНН,
ПродажиОбороты.КоличествоОборот КАК Количество
ИЗ
РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, , ) КАК ПродажиОбороты
ЛЕВОЕ СОЕДИНЕНИЕ
Справочник.Контрагенты КАК СпрКонтрагенты
ПО
ПродажиОбороты.Покупатель = СпрКонтрагенты.Ссылка
Такой подход позволяет оптимизатору СУБД построить более эффективный план запроса. Также обратите внимание на состав полей в группировке. Использование Период с точностью до секунды в оборотном отчете за год избыточно. Если требуется аналитика по месяцам, используйте дополнение периода Месяц непосредственно в параметрах виртуальной таблицы.
Часто разработчики используют временные таблицы (ВТ) для промежуточных расчетов, например, для вычисления средневзвешенной цены. Однако СКД — это мощный генератор запросов, который сам умеет оптимизировать выборку. Когда мы помещаем данные во временную таблицу, мы лишаем СКД возможности «вырезать» лишние поля и накладывать отборы на самом раннем этапе выполнения запроса к СУБД.
Проанализируем ситуацию: если расчет средней цены (Стоимость / Количество) перенести из текста запроса в Ресурсы СКД или Вычисляемые поля, платформа сможет оптимизировать запрос так, что в выборку попадут только те измерения, которые пользователь выбрал в настройках отчета. Это критически важно для сокращения объема данных, передаваемых с SQL-сервера на сервер приложений 1С.
Выясним причину, по которой расчет стоимости «на лету» (СУММА(Цена * Количество)) замедляет отчет. Любая арифметическая операция над миллионами строк в запросе блокирует использование предрассчитанных агрегатов.
Рекомендация: Добавьте в регистр накопления ресурс Сумма (или Стоимость). Заполняйте его один раз при проведении документа. В этом случае запрос к виртуальной таблице оборотов превратится в простое чтение готовых сумм из таблицы итогов, что выполняется в десятки раз быстрее, чем построчное умножение.
Если отчет «зависает» на долгое время, а процесс rphost потребляет всю доступную память, мы имеем дело с утечкой памяти или свопингом (сбросом данных на диск). Это часто происходит, когда СКД пытается обработать огромный массив данных (например, 200 000 строк с множеством группировок) в оперативной памяти.
Для решения этой проблемы можно применить стратегию использования Таблицы Значений (ТЗ) как источника данных для СКД:
ТаблицуЗначений.ВнешнийИсточникДанных.Это позволяет жестко контролировать момент выполнения запроса и объем занимаемой памяти, избегая «магии» автоматической генерации запросов СКД, которая иногда бывает неоптимальной для сложных отчетов.
Нельзя забывать и про «гигиену» базы данных. Даже идеально написанный запрос будет тормозить на фрагментированных индексах или устаревшей статистике. Регулярно выполняйте следующие операции на уровне SQL-сервера:
Подводя итог, можно сказать, что достижение скорости в 30 секунд для отчета по 2 млн записей — задача реальная. Она требует комплексного подхода: перехода на регистры оборотов, отказа от вычислений и разыменований внутри запроса, грамотного использования ресурсов СКД и регулярного технического обслуживания СУБД.