Как устранить задержки при поиске номенклатуры в обработке «Подбор товаров» в УТ 11

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

Проблема низкой производительности динамических списков при поиске товаров — одна из самых сложных и распространенных в высоконагруженных системах на базе 1С:Управление торговлей 11. Часто мы сталкиваемся с ситуацией, когда при объеме номенклатуры всего в 10–15 тысяч позиций поиск начинает «подвисать» на несколько минут. Разберем детально, почему это происходит, как проанализировать проблему на уровне СУБД и какие шаги предпринять для оптимизации.

Анализируем причину деградации производительности

Давайте рассмотрим типичную ситуацию: в конфигурации используется стандартная форма подбора, но справочник Номенклатура вынесен в расширение. При этом поиск по строке (например, по наименованию) выполняется крайне медленно. Проанализируем SQL-запрос, который генерирует платформа. В нем мы увидим огромное количество конструкций CASE WHEN и множество соединений LEFT OUTER JOIN.

Одной из критических проблем является возникновение так называемого неявного Cross Join. Посмотрим на фрагмент SQL-запроса:


LEFT OUTER JOIN (SELECT T7._Fld12313 AS Fld12313_, T7._Fld12312 AS Fld12312_ 
FROM dbo._InfoRgSL27042 T7 
WHERE ((T7._Fld1048 = @P172)) AND (((T7._Fld1111 = @P173)))) T6 ON 1=1

Условие ON 1=1 сигнализирует о том, что в запросе динамического списка используется соединение с таблицей, где не указаны поля связи. В итоге SQL-сервер пытается соединить каждую строку номенклатуры со всеми строками из присоединяемой таблицы. Даже если там одна запись, оптимизатор может выбрать неэффективный план выполнения, что приведет к сканированию всей таблицы (Index Scan) вместо точечного поиска (Index Seek).

Влияние расширений на скорость поиска

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

В контексте динамического списка подбора, который и так перегружен соединениями с виртуальными таблицами остатков и цен, это создает кумулятивный эффект. Оптимизатору СУБД становится все сложнее построить оптимальный план запроса, особенно при использовании оператора LIKE с процентом в начале строки (%прокл%), который исключает использование классических индексов.

Настройка технологического журнала для диагностики

Если поиск работает медленно, но в журнале регистрации нет ошибок, нам необходимо настроить Технологический журнал (ТЖ). Обычная настройка «только исключения» не покажет нам долгие запросы, так как они завершаются успешно, просто долго.

Выясним, как правильно сконфигурировать logcfg.xml для отлова проблемных мест. Нам нужно событие DBMSSQL, а длительность (Duration) в версии 8.3 считается в микросекундах (одна миллионная секунды). Настроим сбор запросов длительностью более 1 секунды:


<config xmlns="http://v8.1c.ru/v8/tech-log">
  <log location="C:\LOGS\SLOW_QUERIES" history="24">
    <event>
      <eq property="Name" value="DBMSSQL"/>
      <gt property="Duration" value="1000000"/>
    </event>
    <property name="All"/>
  </log>
</config>

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

Разбор текста запроса динамического списка

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


ВЫБРАТЬ
    СправочникНоменклатура.Ссылка КАК Ссылка,
    СправочникНоменклатура.Наименование КАК Наименование,
    ВЫРАЗИТЬ(ЕСТЬNULL(СвободныеОстатки.ВНаличииОстаток, 0) КАК ЧИСЛО(15, 3)) КАК ВНаличииОстаток,
    ВЫРАЗИТЬ((ЕСТЬNULL(СвободныеОстатки.ВНаличииОстаток, 0) - ЕСТЬNULL(СвободныеОстатки.ВРезервеПодЗаказОстаток, 0)) КАК ЧИСЛО(15, 3)) КАК Доступно
ИЗ
    Справочник.Номенклатура КАК СправочникНоменклатура
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.СвободныеОстатки.Остатки(&Период, Склад = &Склад) КАК СвободныеОстатки
    ПО СвободныеОстатки.Номенклатура = СправочникНоменклатура.Ссылка
ГДЕ
    НЕ СправочникНоменклатура.ЭтоГруппа

Проблема этого запроса в том, что при использовании в динамическом списке платформа добавляет в него условия поиска. Если пользователь вводит строку поиска, 1С оборачивает этот запрос и добавляет фильтр ГДЕ Наименование ПОДОБНО %Текст%. При наличии LEFT JOIN с виртуальной таблицей остатков, SQL-сервер может сначала попытаться рассчитать остатки для всех 13к позиций, а уже потом фильтровать по наименованию. Это и вызывает задержку.

Рекомендации по оптимизации решения

Разберем по шагам, что можно сделать для исправления ситуации:

  1. Использование полнотекстового поиска (ПП): Переключите режим поиска в настройках подбора с «Поиска по строке» на «Полнотекстовый поиск». Это позволит 1С использовать предварительно построенные индексы ПП вместо тяжелого оператора LIKE.
  2. Оптимизация расширения: Проверьте, индексируются ли реквизиты, добавленные в расширение. Если вы ищете по артикулу или коду, которые переопределены в расширении, убедитесь, что в метаданных расширения для них стоит признак Индексировать.
  3. Упрощение динамического списка: Если бизнес-процесс позволяет, попробуйте отключить отображение цен или остатков по всем складам в форме подбора. Это уберет лишние LEFT JOIN из итогового SQL-запроса.
  4. Обновление статистики SQL: Выполните регламентную операцию UPDATE STATISTICS для таблиц номенклатуры и регистров остатков. Часто «внезапные» тормоза связаны с тем, что SQL-сервер использует устаревшие данные о распределении значений в таблицах и строит неверный план.
  5. Режим «Остатки товаров» в подборе: В новых версиях УТ 11 предусмотрен механизм фонового расчета остатков. Если ваша версия позволяет, рассмотрите возможность обновления до более актуального релиза (например, 11.4.13+), где механизмы динамических списков в подборе были значительно переработаны и оптимизированы.

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

← На главную