При работе с крупными информационными базами 1С программисты часто сталкиваются с деградацией производительности запросов к периодическим регистрам сведений. Особенно остро проблема проявляется при использовании виртуальной таблицы СрезПоследних. В данной статье мы подробно разберем ситуацию и замерим производительность, когда запрос к регистру объемом всего в 200 000 записей выполняется более 5 минут, и найдем эффективные способы оптимизации.
Рассмотрим типичную ситуацию. Имеется независимый периодический регистр сведений ОстаткиТоваровПоставщиков. Его измерения включают номенклатуру, партнера и склад, а ресурс хранит количество остатка. При попытке получить актуальные данные на определенную дату с помощью простейшего запроса система "зависает":
ВЫБРАТЬ ПЕРВЫЕ 100
ОстаткиТоваровПоставщиков.Номенклатура КАК Номенклатура,
ОстаткиТоваровПоставщиков.Поставщик КАК Поставщик,
ОстаткиТоваровПоставщиков.СкладПоставщика КАК СкладПоставщика,
ОстаткиТоваровПоставщиков.Остаток КАК Остаток
ИЗ
РегистрСведений.ОстаткиТоваровПоставщиков.СрезПоследних(&ДатаСреза, ) КАК ОстаткиТоваровПоставщиков
УПОРЯДОЧИТЬ ПО
Период УБЫВ
Проанализируем, что происходит "под капотом" СУБД. Когда мы обращаемся к виртуальной таблице СрезПоследних, платформа 1С не просто читает данные из таблицы, она генерирует сложный SQL-запрос. Если для регистра не включены специальные механизмы оптимизации, СУБД приходится выполнять вложенный подзапрос для поиска максимальной даты (MAX(Period)) для каждой комбинации измерений. При большом количестве записей и отсутствии подходящих индексов это приводит к полному сканированию таблицы (Clustered Index Scan), что крайне ресурсоемко.
Самым эффективным методом решения данной проблемы в современных версиях платформы 1С 8.3 (начиная с 8.3.8) является включение функционала итогов для независимых периодических регистров сведений. Разберем по шагам, как это работает и почему это помогает.
_InfoRgLast. В этой таблице всегда хранятся только самые актуальные записи на текущий момент времени.СрезПоследних без указания конкретной даты (на текущее время), 1С больше не вычисляет срез "на лету". Она просто берет данные из готовой таблицы _InfoRgLast. Это происходит практически мгновенно.В рассматриваемом нами случае включение итогов позволило сократить время выполнения запроса с 5 минут до 30 секунд. Это колоссальный прирост, который достигается простым изменением настроек метаданных без переписывания кода.
Проанализируем использование конструкций ВЫБРАТЬ ПЕРВЫЕ и УПОРЯДОЧИТЬ ПО. Часто программисты добавляют сортировку по полю Период в виртуальной таблице среза. Однако стоит помнить, что в виртуальной таблице СрезПоследних для каждой комбинации измерений по определению существует только одна запись — самая последняя. Сортировка по периоду здесь может иметь смысл только в том случае, если вы хотите увидеть сначала самые "свежие" изменения среди всех товаров.
Важный нюанс: Сочетание TOP (в SQL) и ORDER BY часто сбивает с толку оптимизатор СУБД. Если индекс по периоду не является лидирующим, SQL Server может решить сначала получить все 200 000 записей среза, сохранить их во временной таблице TempDB, отсортировать и только потом отдать первые 100. Это и создает задержку. Попробуйте выполнить запрос без сортировки, чтобы проверить, в ней ли дело.
Выясним, как структура регистра влияет на скорость. В исходном запросе фигурировал реквизит ОстатокАктуален. Рассмотрим техническую деталь: в SQL-запросе для получения значений реквизитов платформе приходится выполнять дополнительное соединение (LEFT JOIN) виртуальной таблицы среза с основной физической таблицей регистра по всем измерениям и периоду.
Если ваша задача требует максимальной производительности, проанализируйте возможность переноса критически важных реквизитов в состав ресурсов. Ресурсы хранятся непосредственно в таблице итогов, и их получение не требует дополнительных соединений таблиц в базе данных.
Если программные методы и настройки метаданных не дают мгновенного результата, необходимо обратить внимание на состояние базы данных на уровне MS SQL Server:
UPDATE STATISTICS.REORGANIZE или REBUILD индексов.Подводя итог, если вы столкнулись с медленной работой среза последних, выполните следующие шаги:
UPDATE STATISTICS _InfoRgXXXX.Следуя этим рекомендациям, мы сможем добиться стабильной и быстрой работы даже на таблицах с миллионами записей, обеспечивая комфортную работу пользователей с актуальными данными.