Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Вопрос к SomewhereSomehow по выбору плана  [new]
Любопытный гость
Guest
Простенький примерчикх
drop table Tab1, Tab2
go
create table Tab1(id int)
create table Tab2(id int)
insert Tab2 select object_id from sys.objects
insert Tab1 select top 1 object_id from sys.objects
create statistics stat1 on Tab1(id)
create statistics stat2 on Tab2(id)
go
select * from Tab1 inner join Tab2 on Tab2.id = Tab1.id
select * from Tab1 inner loop join Tab2 on Tab2.id = Tab1.id

Оптимизатор выберет план с хешем, а не с циклами.
Почему так? Ведь с циклами оценка дешевле.

MS SQL 2008 R2

Спасибо.
1 фев 17, 17:09    [20170552]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос к SomewhereSomehow по выбору плана  [new]
Mike_za
Member

Откуда: Москва
Сообщений: 1176
Любопытный гость,

а если так?

create clustered index  PK on Tab1(id)
create clustered index  PK on Tab2(id)


то у меня выбирает Loop.

может дело в том, что хеш предпочтительнее, когда нет индексов для полей соединения
1 фев 17, 18:46    [20170881]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос к SomewhereSomehow по выбору плана  [new]
Критик
Member

Откуда: Москва / Калуга
Сообщений: 35387
Блог
с индексом нормально
1 фев 17, 18:48    [20170887]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос к SomewhereSomehow по выбору плана  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6802
Любопытный гость,

если нет подходящих индексов - будет hash
1 фев 17, 19:03    [20170925]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос к SomewhereSomehow по выбору плана  [new]
Любопытный гость
Guest
TaPaK,

Почему?
1 фев 17, 19:22    [20170989]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос к SomewhereSomehow по выбору плана  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
Любопытный гость
TaPaK,

Почему?
Потому что луп без индексов будет приводить к многократному скану внешней таблицы, а hash join просканит каждую таблицу по разу.

Сообщение было отредактировано: 1 фев 17, 19:28
1 фев 17, 19:26    [20170997]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос к SomewhereSomehow по выбору плана  [new]
Любопытный гость
Guest
Гавриленко Сергей Алексеевич
Потому что луп без индексов будет приводить к многократному скану внешней таблицы, а hash join просканит каждую таблицу по разу.
Вы наверное хотели сказать внутренней?
Я понимаю про многократный скан.
Вопрос немколько другой. В примере стоимость запроса с лупами ниже стоимлсти с хешем.
Получается стоимость не единственный критерий выбора плана?
1 фев 17, 19:51    [20171054]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос к SomewhereSomehow по выбору плана  [new]
felix_ff
Member

Откуда: Moscow
Сообщений: 1837
Любопытный гость,

Проверьте стоимость оператора внутри хэш соединения и внутри nl. Скан для хэша в процентном соотношении должен быть ниже
1 фев 17, 19:54    [20171062]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос к SomewhereSomehow по выбору плана  [new]
Любопытный гость
Guest
felix_ff,

Картинка с другого сайта.
1 фев 17, 20:14    [20171095]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос к SomewhereSomehow по выбору плана  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
Любопытный гость,
здравствуйте.

Я уже отвечал на этот вопрос, только в разрезе другого примера вот тут Оптимизатор без границ (ч.2), поэтому оттуда, чтоб не перепечатывать:
автор
Учитываются не все альтернативы

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

Оптимизатор, рассматривает не наиболее дешевый вариант из всего множества, он рассматривает наиболее дешевый вариант из имеющегося множества вариантов. Это множество он генерирует сам, последовательно применяя правила преобразования к дереву операторов. Он не применяет все правила ко всем подряд, тоже писал об этом, тут Оптимизатор без границ (ч.1)
автор
Важный момент: правила применяются не все подряд. А только те, что соответствуют некоторому шаблону для конкретного выражения группы (оператора).
Вариант с Nested Loops не оказывается в этом множестве, т.к. логическое дерево операторов этого запроса и логические свойства его узлов не соответствуют правилу, когда было бы выгодно применить Nested Loops. Так что несмотря на то, что Loop дешевле, он просто не участвует в торгах, поэтому его не выбирают (один из общих резонов, почему разработчики сиквела так сделали, вам озвучил выше Гавриленко Сергей Алексеевич).

Чтобы Nested Loops участвовал в торгах, можно, например, сделать следующее:
select * from Tab1 inner join Tab2 on Tab2.id = Tab1.id
select * from Tab1 inner loop join Tab2 on Tab2.id = Tab1.id

-- Enabling NL without hints
select * from Tab1 inner join Tab2 on Tab2.id = Tab1.id option(fast 1) -- Loop Join, No Join Hint
select * from Tab1 inner join Tab2 on Tab2.id <= Tab1.id and Tab2.id >= Tab1.id -- Loop Join, no Hint, resticted by predicates, no Hash Join possible

Стоимость действительно не единственное, что участвует в выборе плана, но в данном случае, дело даже не в этом. В данном случае, чтобы выбрать из разных альтернатив по стоимости, оптимизатор должен иметь эти альтернативы.
1 фев 17, 21:15    [20171213]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос к SomewhereSomehow по выбору плана  [new]
Любопытный гость
Guest
SomewhereSomehow,

Спасибо!
1 фев 17, 22:38    [20171442]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить