Вопрос о том, как именно 1С "склеивает" таблицы в запросах, часто ставит в тупик даже опытных разработчиков. Кажется, что платформа должна иметь какой-то свой внутренний механизм, но на самом деле ситуация обстоит иначе. Разберем детально, что происходит "под капотом" при выполнении оператора ЛЕВОЕ СОЕДИНЕНИЕ или ВНУТРЕННЕЕ СОЕДИНЕНИЕ.
Для начала проанализируем архитектуру системы. В клиент-серверном варианте платформа 1С выступает в роли транслятора. Когда мы пишем запрос на языке 1С, платформа переводит его на "родной" язык конкретной СУБД (T-SQL для MS SQL Server или PL/pgSQL для PostgreSQL). Сама 1С не выполняет физическое соединение таблиц — эта задача полностью ложится на плечи оптимизатора запросов СУБД.
Оптимизатор СУБД — это сложный программный комплекс, который на основе имеющейся статистики (данных о количестве строк, уникальности значений и распределении данных в индексах) строит план выполнения запроса. Рассмотрим основные алгоритмы, которые может выбрать СУБД для реализации вашего соединения.
СУБД не использует один и тот же метод всегда. В зависимости от объема данных и наличия индексов выбирается наиболее дешевый (с точки зрения ресурсов) вариант:
Выясним причину, по которой один и тот же запрос может работать с разной скоростью. Все дело в индексах. В 1С важно понимать:
Nested Loops.В 1С есть механизм, который неявно создает соединения — это обращение к реквизитам через точку. Проанализируем пример:
ВЫБРАТЬ
Продажи.Номенклатура.Наименование,
Продажи.Склад.Код
ИЗ
РегистрНакопления.Продажи КАК Продажи
На уровне СУБД этот простой запрос превратится в конструкцию с двумя LEFT OUTER JOIN к таблицам справочников "Номенклатура" и "Склады". Рассмотрим подробнее опасность: если таких точек в запросе много, СУБД придется строить план для десятка соединений, что может перегрузить оптимизатор. Рекомендуется заменять множественные обращения через точку на явные соединения в тексте запроса, особенно если это касается высоконагруженных участков кода.
Посмотрим на типичную ошибку новичков — использование функций в условии соединения. Например:
ПО НАЧАЛОПЕРИОДА(Т1.Дата, ДЕНЬ) = НАЧАЛОПЕРИОДА(Т2.Дата, ДЕНЬ)
Такое условие делает запрос non-SARGable (Search Argumentable). Это означает, что СУБД не сможет использовать индекс по полю Дата, так как ей нужно сначала вычислить функцию для каждой строки таблицы. В итоге механика соединения деградирует до полного сканирования таблицы (Table Scan), что крайне медленно.
Разберем ситуацию с файловой базой. Здесь нет полноценного SQL-сервера, и используется собственный движок 1С. Его алгоритмы значительно проще и менее "интеллектуальны", чем у MS SQL или PostgreSQL. В файловом варианте практически всегда используется подобие вложенных циклов. Именно поэтому файловые базы так критично теряют в производительности при росте объема данных: отсутствие индекса на соединяемом поле заставляет систему выполнять полный перебор строк (квадратичная сложность).
Механика соединений в 1С — это механика используемой СУБД. Чтобы ваши запросы работали быстро, следуйте правилам:
ПО, чтобы не блокировать использование индексов.Понимание этих принципов позволяет писать запросы, которые эффективно масштабируются и не вызывают проблем с производительностью даже на терабайтных базах данных.