Comments 10
Все открытые уроки мы естественно записываем в высоком качестве. В этот раз, к сожалению, возникли внезапные проблемы с записью, поэтому качество картинки пострадало.
Но, как я заметил, над образом филина здорово поработали; )
Это нивелирует некоторые огрехи.
Хэш-соединение иллюстрированно неверно.
Верная иллюстрация:
Делим скитлз и эмэмдэмс, каждый на 3 кучки: «холодные цвета», «теплые цвета», «нейтральные цвета». В которые сваливаем, соответственно, голубые-зеленые, красные-оранжевые-желтые, и коричневые конфетки. То, что кучки получились разные это нормально, функция хеширования так выбрана. :-)
Потом, каждый элемент каждой кучки последовательно сравниваем с каждым элементом соответствующей кучки, т.е. теплую кучку — с теплой, холодную — с холодной, нейтральную — с нейтральной, и, в случае совпадения цвета — отбираем в результирующую выборку.
Ускорение, в сравнении с nested loop достигается из-за того, что элементы, соответствующие данному, приходится искать не во всём соединяемом множестве, а в относительно узком подмножестве, «теплых цветах», например.
Но, зато обе кучи, скитлз и эмэмдемс необходимо предварительно просмотреть и разделить на «предварительные» кучки, на что тратится силы, время, и место.
Выигрыша по скорости в сравнением с merge — нету, но для merge на входе нужна уже предварительно отсортированная выборка.
Кстати, merge тоже неверно иллюстрирована.
Верная иллюстрация выглядит так:
Предположим, конфетки у нас уже отсортированы в линеечку, рядом друг с другом, в соответствие с правилом радуги, ну или палитрой художника.
Тогда соединять кучки можно одним движением руки, просто сгребая две рядом стоящие линейки одного цвета.
То, что они отсортированы — сильно облегчает дело, т.к. видно, где заканчивается один цвет, и начинается другой.

Как то так :-)
Спасибо!
В вашей иллюстрации получается лучше показать разницу между хэш функцией и значениями в таблице. И тоже очень интересный момент, мне кажется, который я не проговорила — за счет чего получается ускорение по сравнению с Nested loops.
Про мерж — отличная иллюстрация про радугу, так как в мерж они уже отсортированы благодаря индексам, но в примере с баночками это не очень наглядно.
Буду пользоваться с вашего позволения улучшенными примерами.
Обязательно, более того, обычно оно лучше. В этот раз, увы, возникли внезапные технические проблемы с записью.
В сравнении с nested loop — не ускорение. А уменьшение времени выборки в некоторых, весьма специфических условиях :-)
Вложенные циклы — вообще самый лёгкий, производительный и универсальный вариант соединения. Но на небольших объемах данных.
И, кстати, в версии 6.0 — 7.0, если мне память не изменяет, только он и был.
Но благодаря некоторым трюкам, как то организация хэш-таблиц, битмап-индексов, предварительной сортировке данных, на БОЛЬШИХ выборках удается получит выигрышь во времени выборки… за счет чего-то.
Например, построение хэш таблиц — очень охочее до процессора мероприятие, и MSSQLSERVER считает его дорогим и применяет неохотно.
Соединение слиянием требует отсортированных входящих потоков, что вообще-то, дорого.
И т.д.
И еще есть нюансы поведения этих вариантов соединения, в случае неадекватной статистики, и как следствие этого — неправильной оценки кардинальности. И это не считая того, что кардинальность может оцениваться неверно из-за каких то проблем в понимании запроса сервером и т.д.
Короче говоря — увидите в плане merge или hash — не спешите радоваться.
И уж, тем более, пользуясь конструкциями типа inner hash join или option (loop join) нужно понимать, зачем и почему вы это делаете, и почему без этого нельзя обойтись. Тем более, что скорее нужно обойтись.

Как то так.
Про hint ы на то как делать соединение таблиц, было пару случаев где оптимизация свелась просто к убиранию хинта и все стало работать в разы быстрее. Все-таки прибитое гвоздями надо периодически мониторить и смотреть как оно там, а так как кода много, про существующие в коде хинты часто забывают. Видимо хинт прожил в том месте, откуда я его убрала, довольно долго и возможно пережил переезд на новую версию SQL Server.
В разделе Nested Loop в действительном плане запроса(скрин из management studio) не выполняется перебор(Nested Loop 0%), планировщик использует кластеризованные индексы(IX_mms_color 49% и IX_skittles_color 51%) для получения данных
Only those users with full accounts are able to leave comments. Log in, please.