Представим, что перед СУБД (Оптимизатором) стоит задача соединить 2 таблицы (ЛЕВОЕ, ВНУТРЕННЕЕ и т.д.). Чтобы соединить их между собой, СУБД необходимо выполнить условия сравнения полей, по которым происходит соединение, и выбрать соответствующие строки.
Используется несколько способов, в зависимости от их размеров и других условий.
NESTED LOOPS (Вложенные циклы)
В этом способе, для каждой строки первой таблицы выполняется поиск во второй (цикл). Этот способ самый дорогой для СУБД, т.к. выполняется много операций в цикле.
Соединение циклом — это самый простой (с точки алгоритма) способ, но и самый не оптимальный в случае больших массивов данных.
Например, для соединения таблиц в 10 тысяч и 50 тысяч записей потребуется сделать 10 000 * 50 000 = 500.000.000 (500 млн.) операций сравнения. Соединение таким способом больших по объему данных – основная причина долгого выполнения запросов, СУБД просто подвисает на время выполнения цикла.
HASH JOIN (Хеширование)
В таком способе из двух таблиц выбирается меньшая и помещается в отдельную область оперативной памяти. На основе нее строится так называемый hash map (или что-то типа индекса). В итоге идет обход строк большой таблицы, и выполняется проверка на существование ключа поиска в хэш-данных.
Соединение хешированием значительно быстрее, в случае большого массива данных.
Но следует учитывать, что требуются дополнительные ресурсы на построение хэш-данных, а так же СУБД должна знать размеры таблиц, т.е. иметь статистику, чтобы принять решение использовать такой способ соединение.
MERGE JOIN (Слияние)
Для слияния необходимо, чтобы таблицы были заранее отсортированы. Например, мы их отсортировали на предыдущем этапе или выбираем уже упорядоченные данные, скажем, из индексов.
Не стоит забывать, что сортировка — это очень дорогое удовольствие для СУБД.
В этом случае СУБД проходится по двум таблицам одновременно и проверяет на совпадение строк, т.к. в обеих массивах данных они идут в одном порядке. Это, пожалуй, самый быстрый способ.
Условия поиска по индексу
Давайте рассмотрим, какие условия могут подойти для поиска по индексу:
- Равно
- Больше, Больше или равно
- Меньше, Меньше или равно
- Начинается с (подобно “поиск%”)
- В (списке)
По таким условиям, мы можем осуществлять поиск, чтобы он попал в индекс. И, конечно же, не рекомендуется использовать сложные условия.
Выводы
Самым оптимальным способом соединения таблиц является Слияние, далее идет Хеширование и самым не оптимальным является Циклы. Но следует учитывать некоторые особенности:
- Если обе таблицы небольшие или хотя бы одна из таблиц содержит всего лишь несколько строк, то самым оптимальным способом будет являться – вложенные циклы, т.к. это максимально проще и не требует дополнительных накладных затрат на хеширование или сортировку.
- Чтобы использовать способы хешированием и слиянием требуются простые условия соединений (условия поиска по индексу), иначе мы не сможем выполнить алгоритмы соединения.
- Чтобы использовать способы хешированием и слиянием, СУБД необходима информация об этих таблицах: количество строк, сортировка, длина полей и т.д.
Данная тема подробнее рассматривается в пакете видео-курса «Секреты 1С: Эксперта» Шаг 3. Занятие 08-01 Оптимизация запросов.