Преимущества в определении HASH JOIN по сравнению с просто выполнением JOIN? - PullRequest
13 голосов
/ 29 апреля 2009

Каковы преимущества, если таковые имеются, явного выполнения HASH JOIN по сравнению с обычным JOIN (в котором SQL Server определит наилучшую стратегию JOIN)? Например:

select pd.*
from profiledata pd
inner hash join profiledatavalue val on val.profiledataid=pd.id

В приведенном выше упрощенном примере кода я указываю стратегию JOIN, тогда как, если я укажу ключевое слово "hash", SQL Server выполнит MERGE JOIN за кулисами (в соответствии с "фактическим планом выполнения").

Ответы [ 5 ]

13 голосов
/ 29 апреля 2009

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

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

Но со временем, когда данные изменяются / растут или изменяются индексы и т. Д., Ваша подсказка JOIN становится устаревшей и мешает оптимальному плану. Подсказка JOIN может оптимизировать только этот запрос во время разработки с тем набором данных, который у вас есть.

Лично я никогда не указывал подсказку JOIN ни в одном рабочем коде.

Обычно я решал проблему плохого объединения, меняя свой запрос, добавляя / изменяя индекс или разбивая его (например, сначала загрузив временную таблицу). Либо мой запрос был неверным, либо у меня было неявное преобразование типов данных, либо это выявило недостаток в моей схеме и т. Д.

Я видел, как другие разработчики использовали их, но только там, где у них были сложные представления, вложенные в сложные представления, и они вызывали более поздние проблемы при рефакторинге.

Edit:

У меня было преобразование сегодня, когда некоторые коллеги собираются использовать их для принудительного использования неверного плана запросов (с NOLOCK и MAXDOP 1), чтобы «поощрять» переход от устаревших сложных вложенных представлений, которые напрямую вызывает одна из их последующих систем.

3 голосов
/ 20 марта 2013

Когда попробовать хэш-подсказку, как насчет:

  • После проверки наличия адекватных индексов хотя бы на одном из таблицы.
  • После попытки переупорядочить запрос. Такие вещи, как преобразование присоединяется к «в» или «существует», изменяя порядок соединения (который на самом деле в любом случае), перемещая логику из условия where для присоединения к условию и т. д.

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

Зачем использовать любые подсказки соединения (хэш / слияние / цикл с побочным эффектом порядка сил)?

  • Чтобы избежать чрезвычайно медленного выполнения (.5 -> 10.0 с) угловых случаев.
  • Когда оптимизатор последовательно выбирает посредственный план.

Предоставленная подсказка, вероятно, будет неидеальной для некоторых обстоятельств, но обеспечивает более последовательно предсказуемое время выполнения. Ожидаемый сценарий наихудшего и наилучшего вариантов должен быть предварительно протестирован при использовании подсказки. Предсказуемое время выполнения критически важно для веб-сервисов, где предпочтительным является строго оптимизированный номинальный запрос [.3s, .6s], а не запрос, который может варьироваться, например, [.25, 10.0s]. Могут происходить большие отклонения во время выполнения, при этом статистика обновляется и применяются лучшие практики.

При тестировании в среде разработки следует также отключить «читерство», чтобы избежать отклонений во время выполнения в горячем / холодном режиме. Из другого поста ...

CHECKPOINT -- flushes dirty pages to disk
DBCC DROPCLEANBUFFERS -- clears data cache
DBCC FREEPROCCACHE -- clears execution plan cache

Последний параметр может совпадать с подсказкой (перекомпилировать).

MAXDOP и загрузка машины также могут иметь огромное значение во время выполнения. Материализация CTE во временных таблицах также является хорошим механизмом блокировки и кое-что стоит рассмотреть.

2 голосов
/ 29 апреля 2009

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

1 голос
/ 29 апреля 2009

Единственный совет, который я когда-либо видел в коде доставки, был OPTION (FORCE ORDER). Глупая ошибка в оптимизаторе SQL-запросов может привести к созданию плана, который попытается объединить нефильтрованный varchar и уникальный идентификатор. Добавление FORCE ORDER заставило его сначала запустить фильтр.

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

0 голосов
/ 29 апреля 2009

Оптимизатор логического плана не гарантирует вам, что он найдет оптимальное решение: точный алгоритм слишком медленный для использования на рабочем сервере; вместо этого используются некоторые жадные алгоритмы.

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

...