Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Вопрос по плану выполнения запроса  [new]
НеизвестныйГ
Guest
Доброе время суток, версия сервера 2014SP1

Создаем таблицы:
use tempdb
go

if object_id('t1', 'u') is not null
	drop table t1
if object_id('t2', 'u') is not null
	drop table t2
go

create table t1(id int primary key identity, a int)
create table t2(id int primary key identity, b int not null)
go

insert into t1(a)
select row_number() over (order by (select null)) from sys.all_columns
insert into t2(b)
select row_number() over (order by (select null)) from sys.all_columns
go


Запрос для получения плана выполнения:
select * from t1 where a not in (select b from t2)
go

Получим следующий план:
  |--Hash Match(Right Anti Semi Join, HASH:([tempdb].[dbo].[t2].[b])=([tempdb].[dbo].[t1].[a]), RESIDUAL:([tempdb].[dbo].[t1].[a]=[tempdb].[dbo].[t2].[b]))
       |--Clustered Index Scan(OBJECT:([tempdb].[dbo].[t2].[PK__t2__3213E83FE6646FA1]))
       |--Nested Loops(Left Anti Semi Join, WHERE:([tempdb].[dbo].[t1].[a] IS NULL))
            |--Clustered Index Scan(OBJECT:([tempdb].[dbo].[t1].[PK__t1__3213E83F71C13732]))
            |--Top(TOP EXPRESSION:((1)))
                 |--Clustered Index Scan(OBJECT:([tempdb].[dbo].[t2].[PK__t2__3213E83FE6646FA1]))


Вопрос: зачем нужен оператор обращения к t2 в ветке операторов:
       |--Nested Loops(Left Anti Semi Join, WHERE:([tempdb].[dbo].[t1].[a] IS NULL))
            |--Clustered Index Scan(OBJECT:([tempdb].[dbo].[t1].[PK__t1__3213E83F71C13732]))
            |--Top(TOP EXPRESSION:((1)))
                 |--Clustered Index Scan(OBJECT:([tempdb].[dbo].[t2].[PK__t2__3213E83FE6646FA1]))
19 май 16, 11:15    [19192555]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по плану выполнения запроса  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6802
НеизвестныйГ,

select * from t1 where a not IN (select b from t2) AND a IS NOT NULL
19 май 16, 11:43    [19192745]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по плану выполнения запроса  [new]
НеизвестныйГ
Guest
TaPaK,

а зачем для проверки предиката t1 обращаться к t2?
19 май 16, 12:32    [19192964]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по плану выполнения запроса  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6802
НеизвестныйГ
TaPaK,

а зачем для проверки предиката t1 обращаться к t2?

не предикат проверяет, а есть ли NULL в вашей t2. проверки на NULL отдельно от всего ибо несравнимы. Хорошо видно если поставить
SET ANSI_NULLS OFF для вашего первоначального запроса
19 май 16, 12:38    [19193006]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по плану выполнения запроса  [new]
НеизвестныйГ
Guest
TaPaK,

Так у меня же "b int not null" ясно объявлено
19 май 16, 12:46    [19193058]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по плану выполнения запроса  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6802
НеизвестныйГ,

делать нечего sql-ю как смотреть как вы таблицы создавали
19 май 16, 12:51    [19193095]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по плану выполнения запроса  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 8839
НеизвестныйГ,

зато a int null.
19 май 16, 13:25    [19193334]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по плану выполнения запроса  [new]
daw
Member

Откуда: Муром -> Москва
Сообщений: 7381
НеизвестныйГ,

я бы предположил: чтобы не сравнивать null-ы из t1.a со всеми значениями в t2.b - для null-ов достаточно проверить только, возвращает ли подзапрос вообще хоть что-то. для небольшого количества записей такого нет (у меня, например, где-то от 70 записей в таблицах такой план начинает строиться).

> делать нечего sql-ю как смотреть как вы таблицы создавали

очень даже есть чего делать. так план уже другой будет:
create table t1(id int primary key identity, a int null)
19 май 16, 13:37    [19193445]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по плану выполнения запроса  [new]
daw
Member

Откуда: Муром -> Москва
Сообщений: 7381
daw,

пардон, вот так, конечно:
так план уже другой будет:
create table t1(id int primary key identity, a int not null)
19 май 16, 13:38    [19193456]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по плану выполнения запроса  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6802
daw,
наверное вы правы. А вообще NOT IN лучше не пользоваться. NOT EXISTS будет оптимальнее как раз из за этой проверки
19 май 16, 13:42    [19193488]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить