Основы плана выполнения - путаница с хэш-соответствием

39

Я начинаю изучать планы выполнения и не понимаю, как именно работает хеш-соответствие и почему оно будет использоваться в простом соединении:

select Posts.Title, Users.DisplayName
From Posts JOIN Users on
Posts.OwnerUserId = Users.Id
OPTION (MAXDOP 1)

введите описание изображения здесь

Насколько я понимаю, результаты сканирования верхнего индекса становятся хэш-значениями, и каждая строка в нижнем кластерном сканировании индекса просматривается. Я понимаю, как работают хеш-таблицы, по крайней мере, до некоторой степени, но я не совсем понимаю, какие именно значения хэшируются в примере, подобном этому.

Что имеет смысл, так это то, что общее поле между ними, id, хэшируется, но если это так, зачем хешировать число?

Кайл Брандт
источник

Ответы:

29

Как цитаты ответа SQLRockstar

лучше всего подходит для больших несортированных входов.

В настоящее время,

  • при сканировании индекса Users.DisplayName (предположительно некластеризованного) вы получаете Users.Id (предполагается кластеризованного) = несортированный
  • Вы также сканируете сообщения на OwnerUserId = несортированные

Это 2 неупорядоченных входа.

Я хотел бы рассмотреть индекс в таблице сообщений на OwnerUserId, включая название. Это добавит некоторый порядок на одну сторону ввода в JOIN + будет охватывать индекс

CREATE INDEX IX_OwnerUserId ON Posts (OwnerUserId) INCLUDE (Title)

Затем вы можете обнаружить, что индекс Users.DisplayName не будет использоваться, а вместо этого будет сканировать PK.

ГБН
источник
1
А, ладно, теперь я вижу, я думал о Users.DisplayName, заказанном PK, но это не так. Теперь использование Hash имеет для меня гораздо больше смысла. Благодарность!
Кайл Брандт
1
Вы также можете попробовать OPTION (FAST n)подсказку, где n - приблизительное число ожидаемых строк. Это будет смещать оптимизатор к вложенным циклам, а не к хеш-соединениям, когда n мало. Причина в том, что хеш-соединения быстры для больших объединений, но имеют высокую стоимость запуска. Вложенные циклы являются дорогими для каждого ряда, но могут начаться очень дешево. Так что это вопрос тонкой настройки на основе ваших фактических данных и схемы доступа.
Гай
1
@ Гай: Лично я предпочел бы иметь индексы, а не намеки. Подсказка хороша только для запроса, когда вы его добавляете. Ака подсказка становится обязательством со временем. Индексы имеют тенденцию быть полезными гораздо дольше.
ГБН
1
это не или-или предложение :-)
Gaius
14

От http://sqlinthewild.co.za/index.php/2007/12/30/execution-plan-operations-joins/

«Хеш-соединение является одной из более дорогих операций соединения, так как для этого требуется создание хеш-таблицы. При этом это соединение лучше всего подходит для больших несортированных входных данных. Оно наиболее интенсивно использует память из всех из соединений

Хеш-соединение сначала считывает один из входных данных и хэширует столбец соединения и помещает полученный хеш-код и значения столбца в хеш-таблицу, созданную в памяти. Затем он читает все строки во втором входном файле, хэширует их и проверяет строки в результирующем хэш-контейнере на наличие соединяющихся строк. "

какие ссылки на этот пост:

http://blogs.msdn.com/b/craigfr/archive/2006/08/10/687630.aspx

НТН

SQLRockstar
источник
Так что, если это просто поля id, я думаю, я не понимаю преимущества хеширования поля id?
Кайл Брандт
+1 за ссылку на блог Крейга Фридмана, есть еще несколько статей о присоединении: blogs.msdn.com/b/craigfr/archive/tags/joins
Джефф
9

Преимущество хеширования числового поля состоит в том, что вы берете большее значение и разбиваете его на более мелкие части, чтобы оно могло поместиться в хеш-таблицу.

Вот как описывает это Грант Фричи:

«Хеш-таблица, с другой стороны, является структурой данных, которая делит все элементы на категории или сегменты одинакового размера, чтобы обеспечить быстрый доступ к элементам. Функция хеширования определяет, в какой сегмент входит элемент. Например, Вы можете взять строку из таблицы, хешировать ее в хеш-значение, а затем сохранить хеш-значение в хеш-таблице. "

Вы также можете получить бесплатную копию его книги "Рассеяние планов выполнения SQL Server" по ссылке из следующей статьи:

Источник: http://www.simple-talk.com/sql/performance/graphical-execution-plans-for-simple-sql-queries/

Джефф
источник
Еще одна интересная серия статей о JOINS
Джефф
Я работаю по-своему, хотя рассекаю планы выполнения SQL Server - это здорово! Но я немного застрял в этом :-P
Кайл Брандт,