При разработке отчетов или обработок в 1С часто возникает задача поиска номенклатуры по коду, состоящему из основного префикса и изменяемого суффикса. Стандартный подход с использованием оператора ПОДОБНО кажется логичным, однако на больших объемах данных он приводит к критическому падению производительности. Давайте разберем, почему это происходит и как оптимизировать такие запросы, чтобы сократить время выполнения с минут до секунд.
Когда мы используем конструкцию Номенклатура.Код ПОДОБНО ВсеКоды.ОсновнойКод + "%", база данных фактически лишается возможности эффективно использовать индексы. При поиске по маске, особенно если она начинается с символов подстановки, СУБД вынуждена сканировать всю таблицу целиком — выполняется операция Full Table Scan. Для справочника с сотнями тысяч элементов это означает колоссальные затраты ресурсов сервера.
Самым эффективным способом ускорения подобных операций является замена строкового сравнения по маске на сравнение диапазонов. Идея заключается в том, чтобы найти все значения, которые начинаются с нашего основного кода, используя границы значений. Мы ищем все элементы, которые больше или равны заданному коду, но строго меньше, чем код, увеличенный на «максимальное значение».
Рассмотрим, как реализовать этот подход на практике:
Для реализации этого метода применим следующий код:
ВЫБРАТЬ
Тбл.КодТовара КАК ОсновнойКод
ПОМЕСТИТЬ ВсеКоды
ИЗ
&Тбл КАК Тбл
;
ВЫБРАТЬ
Номенклатура.Ссылка КАК Номенклатура,
ВсеКоды.ОсновнойКод КАК ОсновнойКод
ИЗ
ВсеКоды КАК ВсеКоды
ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Номенклатура
ПО (Номенклатура.Код >= ВсеКоды.ОсновнойКод)
И (Номенклатура.Код < (ВсеКоды.ОсновнойКод + "яяяяяя"))
При использовании операторов сравнения >= и <, оптимизатор запросов СУБД может задействовать стандартный индекс, построенный по полю Код. Вместо перебора каждой строки, база данных выполняет поиск в индексе (Range Scan), что происходит практически мгновенно. Использование символа 'яяяяяя' в качестве «верхней границы» гарантирует, что мы охватим все возможные вариации суффиксов, так как в строковой сортировке это значение будет «больше» любого реального кода номенклатуры.
Если задача носит критический характер и требует максимальной скорости, рассмотрим другие архитектурные варианты:
Номенклатура отдельный реквизит ОсновнойКод. При записи элемента вы можете автоматически заполнять его (например, через ПриЗаписи), а затем выполнять обычное соединение по равенству =. Это самый быстрый способ работы с данными в 1С.Код), проиндексировано. Без индекса даже самые «быстрые» запросы будут работать медленно.Мы проанализировали основные способы борьбы с медленными запросами при поиске по маске. Переход от оператора ПОДОБНО к диапазонам поиска позволяет радикально повысить производительность, не меняя при этом архитектуру конфигурации. Рекомендуем внедрять этот подход в тех случаях, когда создание дополнительных реквизитов затруднительно или нецелесообразно.