Почему тормозит поиск в подборе товаров при открытии из записанного документа и как это исправить?

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

Каждый администратор и разработчик систем на базе 1С:Предприятие рано или поздно сталкивается с загадочным поведением системы: стандартный поиск в форме подбора товаров начинает сильно зависать (вплоть до нескольких минут). При этом, если открыть этот же подбор из нового, еще не записанного документа — всё работает мгновенно. Также мгновенно отрабатывает поиск непосредственно в самом справочнике Номенклатура.

В этой статье мы подробно разберем, почему возникает эта проблема, проанализируем внутренние механизмы платформы 1С и СУБД MS SQL Server, а также предложим пошаговые инструкции по оптимизации и устранению этой ошибки.

В чем кроется корень проблемы? Разница между оперативной и исторической датой

Для того чтобы понять причину зависания, давайте проанализируем, как платформа 1С работает с остатками и ценами в форме подбора товаров в этих двух сценариях:

  1. Подбор в новом документе (Оперативный режим): Когда документ еще не записан, его дата условно считается текущей (оперативной). Запрос динамического списка формы подбора обращается к виртуальным таблицам остатков и цен на «сейчас». СУБД получает данные напрямую из таблицы рассчитанных итогов регистров накопления (например, _AccumRegTotals). Это происходит практически мгновенно, так как SQL-серверу не нужно производить промежуточные вычисления.
  2. Подбор в записанном документе (Исторический режим): Когда мы открываем подбор из уже существующего документа, система инициализирует форму подбора на конкретную дату и время (момент времени) этого документа. В этот момент СУБД больше не может использовать готовые оперативные итоги. Чтобы рассчитать остатки на вчерашний день (или на любую другую прошлую дату), MS SQL Server вынужден взять ближайшие рассчитанные итоги и начать последовательно вычитать или прибавлять движения из таблицы изменений (_AccumRegChangeRec) за весь промежуток времени до нужной даты. Чем больше документов и движений в вашей базе, тем тяжелее СУБД рассчитывать эти остатки «на лету» в составе сложного запроса динамического списка.

Ситуация усугубляется механизмом под названием Parameter Sniffing (чувствительность к параметрам) на стороне MS SQL Server. СУБД кэширует план выполнения запроса. План, построенный для оперативной даты, кэшируется как оптимальный. Но когда тот же запрос выполняется для конкретной даты старого документа, СУБД применяет старый закэшированный план, который для этой даты оказывается крайне неэффективным, что приводит к полному сканированию таблиц (Table Scan) вместо быстрого поиска по индексам (Index Seek).

Анализ влияния регистра «Цены номенклатуры»

Очень часто основная задержка происходит не из-за регистра остатков, а при обращении к периодическому регистру сведений ЦеныНоменклатуры через виртуальную таблицу СрезПоследних. Если в метаданных регистра сведений не включена опция «Разрешить итоги: Срез последних», то при запросе данных на прошлую дату платформа строит тяжелейший вложенный запрос с группировками для поиска максимального периода по каждой позиции номенклатуры. На больших базах это гарантированно приводит к зависанию интерфейса.

Пошаговое руководство по устранению проблемы

Рассмотрим подробнее практические шаги, которые помогут вам вернуть былую скорость работы формы подбора товаров.

Шаг 1. Поиск документов и записей с «будущими» датами

Одной из частых причин «слома» механизма расчета итогов является наличие в базе документов или записей регистров со случайными будущими датами (например, из-за опечатки оператора или сбоя при импорте данных была записана дата 2029 или 3999 год). Даже одна такая запись заставляет СУБД некорректно строить планы запросов.

Для поиска таких записей выполним следующий запрос в консоли запросов:


ВЫБРАТЬ
	ЦеныНоменклатуры.Номенклатура КАК Товар,
	ЦеныНоменклатуры.Период КАК НекорректныйПериод
ИЗ
	РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры
ГДЕ
	ЦеныНоменклатуры.Период > &ТекущаяДата

Если запрос вернул строки, необходимо программно или вручную исправить даты этих документов на корректные.

Шаг 2. Настройка и пересчет итогов регистров

Если в базе давно не выполнялось регламентное обслуживание итогов, СУБД тратит слишком много ресурсов на расчет остатков на историческую дату. Выполним следующие действия:

  1. Откроем базу в режиме Конфигуратор.
  2. Перейдем в меню Администрирование — Тестирование и исправление...
  3. Установим флаг напротив пункта Пересчет итогов и запустим процесс выполнения.
  4. Также убедимся, что границы рассчитанных итогов в режиме «Управление итогами» установлены на актуальный месяц. Не допускайте ситуации, когда минимальный хранимый период итогов сильно отстает от текущей даты.

Шаг 3. Включение поддержки итогов для среза последних

Если вы работаете в нетиповой или измененной конфигурации (либо хотите оптимизировать типовую через расширение), обязательно проверьте свойства регистра сведений ЦеныНоменклатуры (или аналогичного регистра цен, используемого в подборе):

  1. Найдите нужный периодический регистр сведений в дереве метаданных.
  2. Откройте свойства регистра и перейдите на вкладку «Основные».
  3. Убедитесь, что свойство «Разрешить итоги: Срез последних» установлено в значение Истина. Это позволит платформе физически хранить таблицу срезов последних на уровне СУБД, что ускорит выполнение запросов в десятки раз.

Шаг 4. Оптимизация кода запроса: отключение среза цен на историческую дату

Давайте зададимся логичным вопросом: зачем нам при подборе товаров в старый документ видеть цены, которые были актуальны на дату этого документа? Ведь мы подбираем товар прямо сейчас, и продавать его будем по актуальным текущим ценам! Получение цен «задним числом» в подборе в 95% случаев не имеет практического смысла.

Проанализируем программный код инициализации подбора. Нам нужно сделать так, чтобы параметры получения цен и остатков всегда устанавливались на текущую дату, независимо от даты документа.

Для этого в общем модуле ПодборТоваровСервер (или в модуле формы подбора) найдем место установки параметров запроса динамического списка и заменим дату документа на текущую дату сеанса. Посмотрим на пример реализации через расширение:


&Вместо("УстановитьПараметрыДинамическогоСписка")
Процедура ИТ_УстановитьПараметрыДинамическогоСписка(ПараметрыПодбора)
	
	// Переопределяем дату на текущую, чтобы СУБД использовала оперативные итоги
	Если ПараметрыПодбора.Свойство("ДатаДокумента") Тогда
		ПараметрыПодбора.ДатаДокумента = ТекущаяДатаСеанса();
	КонецЕсли;
	
	// Вызываем оригинальный обработчик с подмененными параметрами
	ПродолжитьВызов(ПараметрыПодбора);
	
КонецПроцедуры

Этот простой шаг полностью решает проблему зависания, так как СУБД всегда будет мгновенно получать остатки и цены из оперативных итогов, а не рассчитывать их за прошлые периоды.

Шаг 5. Профилактика полнотекстового поиска (ПТП)

Если зависание происходит именно в момент ввода четвертого символа в поисковую строку, дело в индексе полнотекстового поиска. При вводе коротких строк (1-3 символа) платформа ищет по простому условию ПОДОБНО, а при вводе более длинных строк задействует полнотекстовый индекс.

Для исправления работы ПТП выполним следующие действия:

  1. Запустим программу в режиме «Предприятие» под правами администратора.
  2. Перейдем в раздел Администрирование — Поддержка и обслуживание — Полнотекстовый поиск данных.
  3. Нажмем кнопку Очистить индекс, а затем — Обновить индекс.

Шаг 6. Отключение неиспользуемых функциональных опций

Запрос подбора товаров в типовых конфигурациях (например, УТ 11.3 / 11.4) динамически усложняется в зависимости от включенных функциональных опций. Особое влияние на производительность оказывает опция «Использовать упаковки». Если на вашем предприятии учет в упаковках не ведется, обязательно отключите эту опцию в настройках номенклатуры. Это исключит из запроса подбора тяжелые левые соединения (LEFT JOIN) с таблицами упаковок, что существенно облегчит работу планировщика запросов MS SQL Server.

Применяя данные шаги по шагам, вы сможете локализовать причину падения производительности и вернуть пользователям возможность быстрой и комфортной работы с подбором товаров в любых документах.

← На главную