Рассмотрим частую задачу, с которой сталкиваются разработчики при работе с типовыми и околотиповыми конфигурациями 1С — поиск выданного счета-фактуры по документу-основанию и контрагенту. На первый взгляд, задача тривиальная, но неправильное написание запроса может привести к серьезным проблемам с производительностью. Проанализируем исходный код, выясним причину медленной работы и разберем по шагам, как кардинально ускорить такой запрос.
Посмотрим на пример запроса, который часто пишут начинающие специалисты:
ВЫБРАТЬ
СчетФактураВыданный.Ссылка
ИЗ
Документ.СчетФактураВыданный КАК СчетФактураВыданный
ГДЕ
СчетФактураВыданный.ДокументОснование.Ссылка = &Ссылка
И СчетФактураВыданный.Контрагент = &Контрагент
Основная проблема кроется в конструкции СчетФактураВыданный.ДокументОснование.Ссылка. Разберем подробнее, что здесь происходит. Обращение к ссылочному полю через точку (разыменование ссылки) заставляет платформу 1С неявно создавать левое соединение (Left Join) с таблицей документа-основания на уровне СУБД. Это сильно бьет по скорости выполнения, особенно в больших базах данных.
Чтобы избежать неявных соединений, сравнивать значения всегда нужно напрямую, обращаясь к самому полю, а не к его свойствам:
ВЫБРАТЬ
СчетФактураВыданный.Ссылка
ИЗ
Документ.СчетФактураВыданный КАК СчетФактураВыданный
ГДЕ
СчетФактураВыданный.ДокументОснование = &Ссылка
И СчетФактураВыданный.Контрагент = &Контрагент
Проанализируем ситуацию дальше. В новых типовых конфигурациях (таких как Бухгалтерия 3.0, ERP, УТ, КА) структура метаданных изменилась. Поскольку один счет-фактура может быть выписан на несколько накладных или актов (реализаций), документы-основания были перенесены из реквизитов шапки в специализированную табличную часть ДокументыОснования.
Поэтому искать документ-основание нужно не в основной таблице документа, а в табличной части. Посмотрим на актуальный пример запроса:
ВЫБРАТЬ
СчетФактураВыданныйДокументыОснования.Ссылка КАК СчетФактура
ИЗ
Документ.СчетФактураВыданный.ДокументыОснования КАК СчетФактураВыданныйДокументыОснования
ГДЕ
СчетФактураВыданныйДокументыОснования.ДокументОснование = &Ссылка
Поле ДокументОснование имеет составной тип (в него входят реализации, поступления, возвраты и многие другие документы). Когда платформа строит SQL-запрос, она может соединять множество лишних таблиц для проверки этого поля. Чтобы отсечь лишние таблицы на уровне СУБД и значительно повысить производительность, применим оператор приведения типа ВЫРАЗИТЬ.
Рассмотрим, как это выглядит в коде (предположим, основанием выступает документ реализации):
ВЫБРАТЬ
ТабЧасть.Ссылка КАК СчетФактура
ИЗ
Документ.СчетФактураВыданный.ДокументыОснования КАК ТабЧасть
ГДЕ
ВЫРАЗИТЬ(ТабЧасть.ДокументОснование КАК Документ.РеализацияТоваровУслуг) = &Ссылка
Поиск напрямую по физическим таблицам документов не всегда является лучшим решением. Разберем альтернативные, более быстрые методы:
ЖурналУчетаСчетовФактур или регистры накопления по учету НДС (например, НДСПродажи). Измерения в регистрах (контрагент, документ-основание) уже проиндексированы, поэтому поиск отрабатывает моментально.КритерииОтбора. Запрос к виртуальной таблице, например КритерииОтбора.СвязанныеДокументы, автоматически использует нужные индексы и позволяет найти связанные документы максимально штатным и оптимизированным способом.Даже оптимизированный запрос по таблице документов можно улучшить. Рассмотрим финальные штрихи:
Ссылка.Проведен = ИСТИНА.ВЫБРАТЬ ПЕРВЫЕ 1. Это позволит серверу остановить поиск при первом же совпадении.Применяя эти комплексные методы, вы сможете писать быстрые и безопасные для производительности базы данных запросы.