В целом, что заставляет оптимизатор SQL-запроса решить между вложенным циклом и хэшированием.
NESTED LOOPS
хорошо, если условие внутри цикла sargable, то есть индекс может быть использован для ограничения количества записей. Для такого запроса, как
, при ведущей позиции a
, будет взята каждая запись из a
и все соответствующие записи в b
должны быть найдены. Если b.b1
проиндексирован и имеет высокую кардинальность, то предпочтительным вариантом будет NESTED LOOP
. В SQL Server
, это также единственный способ выполнить не равенство (что-то кроме условия =
в пункте ON
)
HASH JOIN
является самым быстрым методом, если все (или почти все) записи должны быть разбиты на парсинг. Он берет все записи из b
, строит над ними хэш-таблицу, затем берет все записи из a
и использует значение столбца соединения в качестве ключа для поиска хэш-таблицы.
NESTED LOOPS
занимает это время:
Na * (Nb / C) * R
,
, где Na
и Nb
- это номера записей в a
и b
, C
- это индексная кардинальность, и R
является постоянным временем, необходимым для поиска строки (1
это все поля в SELECT
, Где Где
и ЗАКАЗЧИК ПО
клаузулы охвачены указателем, около 10
, если они не охвачены)
Хэш Джойн
занимает это время:
Na + (Nb * H)
, где H
- это сумма констант, необходимых для построения и поиска хэш-таблицы (по записи). Они запрограммированы в движке.
SQL Server
вычисляет кардинальность, используя статистику таблицы, вычисляет и сравнивает два значения и выбирает наилучший план.
Обычно это будет зависеть от размера присоединяемых наборов.
Я настоятельно рекомендую прочитать "Inside Microsoft SQL Server 2008: T-SQL Querying" Ицика Бен-Гана:
http://www.solidq.com/insidetsql/books/insidetsql2008/
(издание 2005 года также применимо к этой теме)
Он входит в ваш вопрос, как и многие другие, когда речь заходит о том, чтобы получить максимальную отдачу от ваших запросов.
.