Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Вопрос по if exists  [new]
paxmeleon
Member

Откуда:
Сообщений: 67
Добрый день. Может кто подскажет. Нужно проверить наличие дубликатов, как в примере ниже.
Но вот странно что. Если написать так:

select null from Dimension D
inner join DimensionType DT on DT.DimensionTypeID = D.DimensionTypeID
where DT.ExternalDimensionTypeID is not null and D.ExternalDimensionID is not null
group by D.DimensionTypeID, D.ExternalDimensionID
having count(*) > 1
if @@rowcount > 0 ...

работает очень быстро, а вариант

if exists (
select null from Dimension D
inner join DimensionType DT on DT.DimensionTypeID = D.DimensionTypeID
where DT.ExternalDimensionTypeID is not null and D.ExternalDimensionID is not null
group by D.DimensionTypeID, D.ExternalDimensionID
having count(*) > 1
) ...

в десятки раз медленнее. Запрос один и тот же, но почему такая разница в скорости?
Сервер SQL2005.
6 окт 09, 15:49    [7748812]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по if exists  [new]
-=DiM@n=-
Member

Откуда: Москва
Сообщений: 1564
сравните с таким запросом:

if exists (
select * 
from Dimension D
inner join DimensionType DT on DT.DimensionTypeID = D.DimensionTypeID
where DT.ExternalDimensionTypeID is not null and D.ExternalDimensionID is not null
) ...
6 окт 09, 15:54    [7748860]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по if exists  [new]
paxmeleon
Member

Откуда:
Сообщений: 67
-=DiM@n=-,

Ну так тут совсем другой запрос. А у меня в примере два одинаковых по результату запроса. Поэтому не ясно, почему первый отрабатывает мгновенно, а второй десятки секунд, если отличие только в способе проверки результата.
6 окт 09, 15:58    [7748897]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по if exists  [new]
Сергей Мишин
Member

Откуда:
Сообщений: 376
paxmeleon,
Неудачный план запроса видимо-) сравнивали оба плана? Dimension,DimensionType случайно не вьюхи?
6 окт 09, 15:59    [7748898]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по if exists  [new]
-=DiM@n=-
Member

Откуда: Москва
Сообщений: 1564
упс, и вправду не углядел. Сорри, мой запрос совсем другое вернет, нежели первые запросы...
Тогда неплохо бы планы сравнить. Там все видно будет.
6 окт 09, 16:01    [7748912]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по if exists  [new]
paxmeleon
Member

Откуда:
Сообщений: 67
Сергей Мишин,

Да, планы разные. Так вот и не понятно, почему. Вроде же почти одно и то же. И выходит, что if exists не стоит использовать вообще? Нет, вьюх нет. Только две таблицы.
6 окт 09, 16:04    [7748935]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по if exists  [new]
Glory
Member

Откуда:
Сообщений: 104760
paxmeleon
Сергей Мишин,

Да, планы разные. Так вот и не понятно, почему. Вроде же почти одно и то же. И выходит, что if exists не стоит использовать вообще? Нет, вьюх нет. Только две таблицы.

Т.е. вы всегда теперь будете возвращать клиенту проверочный набор, который ему не нужен ?
Почему все таки select null то в запросах ?
6 окт 09, 16:06    [7748951]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по if exists  [new]
paxmeleon
Member

Откуда:
Сообщений: 67
Glory
paxmeleon
Сергей Мишин,

Да, планы разные. Так вот и не понятно, почему. Вроде же почти одно и то же. И выходит, что if exists не стоит использовать вообще? Нет, вьюх нет. Только две таблицы.

Т.е. вы всегда теперь будете возвращать клиенту проверочный набор, который ему не нужен ?
Почему все таки select null то в запросах ?


Если вы посмотрите запрос полностью, то видно, что мне нужно получить признак наличия дубликатов. Сами дубликаты не нужны. А select null, так как данные не важны. Кто-то пишет select 1. ))
6 окт 09, 16:09    [7748963]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по if exists  [new]
paxmeleon
Member

Откуда:
Сообщений: 67
И вопрос не в том, что я буду делать с данными, а в том, почему такая разница в скорости. ((
6 окт 09, 16:10    [7748975]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по if exists  [new]
Glory
Member

Откуда:
Сообщений: 104760
paxmeleon
И вопрос не в том, что я буду делать с данными, а в том, почему такая разница в скорости. ((

Вопрос в том, что эти скрипты порождают разные результаты
6 окт 09, 16:11    [7748983]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по if exists  [new]
Abbey Road
Member

Откуда:
Сообщений: 26
А так?
if (select count(*) from Dimension D
    inner join DimensionType DT on DT.DimensionTypeID = D.DimensionTypeID
    where DT.ExternalDimensionTypeID is not null and D.ExternalDimensionID is not null
    group by D.DimensionTypeID, D.ExternalDimensionID
    having count(*) > 1
   ) > 0
Планы покажете?
Интересно.
6 окт 09, 16:11    [7748985]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по if exists  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
Для корректности сравнения надо бы ещё кеш чистить перед SELECTами...
6 окт 09, 16:15    [7749014]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по if exists  [new]
paxmeleon
Member

Откуда:
Сообщений: 67
Abbey Road
А так?
if (select count(*) from Dimension D
    inner join DimensionType DT on DT.DimensionTypeID = D.DimensionTypeID
    where DT.ExternalDimensionTypeID is not null and D.ExternalDimensionID is not null
    group by D.DimensionTypeID, D.ExternalDimensionID
    having count(*) > 1
   ) > 0
Планы покажете?
Интересно.


Как раз проверил. Так же отрабатывает мгновенно. )) Так что тем более интересно.
6 окт 09, 16:16    [7749018]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по if exists  [new]
paxmeleon
Member

Откуда:
Сообщений: 67
А как выложить планы? В виде .sqlplan файлов? Или скриншотов будет достаточно ))
6 окт 09, 16:33    [7749142]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по if exists  [new]
Abbey Road
Member

Откуда:
Сообщений: 26
paxmeleon
А как выложить планы? В виде .sqlplan файлов? Или скриншотов будет достаточно ))

Тут
6 окт 09, 16:49    [7749278]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по if exists  [new]
aleks2
Guest
paxmeleon
Abbey Road
А так?
if (select count(*) from Dimension D
    inner join DimensionType DT on DT.DimensionTypeID = D.DimensionTypeID
    where DT.ExternalDimensionTypeID is not null and D.ExternalDimensionID is not null
    group by D.DimensionTypeID, D.ExternalDimensionID
    having count(*) > 1
   ) > 0
Планы покажете?
Интересно.


Как раз проверил. Так же отрабатывает мгновенно. )) Так что тем более интересно.


Группировка в запросе = сканированию таблицы. Только идиоты применяют эту технику для проверки наличия дубликатов.

Могет быть у тебя всеж есть Primary Key в табличках? Сильно помогает.

Да и соединение тут выглядит ОЧЕНЬ сомнительно. Нахрен?
6 окт 09, 16:54    [7749311]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по if exists  [new]
paxmeleon
Member

Откуда:
Сообщений: 67
aleks2

Группировка в запросе = сканированию таблицы. Только идиоты применяют эту технику для проверки наличия дубликатов.

Могет быть у тебя всеж есть Primary Key в табличках? Сильно помогает.

Да и соединение тут выглядит ОЧЕНЬ сомнительно. Нахрен?


Наверное не поверишь, мой деликатный друг, но первичные ключи есть в обеих таблицах.
Т.е. DT.DimensionTypeID - первичный ключ в DT,
по DT.ExternalDimensionTypeID построен индекс,
по D.DimensionTypeID построен индекс,
по паре D.DimensionTypeID, D.ExternalDimensionID так же построен индекс.

Теперь вопрос, как же не идиоты проверяют наличие дубликатов? Будьте добры, не поленитесь ответить, мой деликатный друг.
7 окт 09, 08:17    [7751171]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по if exists  [new]
paxmeleon
Member

Откуда:
Сообщений: 67
А вот и план. Надеюсь, так выложил. ))


Rows Executes StmtText StmtId NodeId Parent PhysicalOp LogicalOp Argument DefinedValues EstimateRows EstimateIO EstimateCPU AvgRowSize TotalSubtreeCost OutputList Warnings Type Parallel EstimateExecutions
-------------------- -------------------- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------- ----------- ----------- ------------------------------ ------------------------------ ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------- ------------- ------------- ------------- ----------- ---------------- ------------------------------------------------- -------- ---------------------------------------------------------------- -------- ------------------
1 1 if (
select count(*) from Dimension D
inner join DimensionType DT on DT.DimensionTypeID = D.DimensionTypeID
where DT.ExternalDimensionTypeID is not null and D.ExternalDimensionID is not null
group by D.DimensionTypeID, D.ExternalDimensionID
having count(*) > 1
) > 0 1 1 0 NULL NULL NULL NULL 1 NULL NULL NULL 0,8692667 NULL NULL GeneralQuery 0 NULL
0 0 |--Compute Scalar(DEFINE:([Expr1008]=CASE WHEN [Expr1010]>(0) THEN (1) ELSE (0) END)) 1 2 1 Compute Scalar Compute Scalar DEFINE:([Expr1008]=CASE WHEN [Expr1010]>(0) THEN (1) ELSE (0) END) [Expr1008]=CASE WHEN [Expr1010]>(0) THEN (1) ELSE (0) END 1 0 1E-07 11 0,8692667 [Expr1008] NULL PLAN_ROW 0 1
1 1 |--Nested Loops(Left Outer Join) 1 3 2 Nested Loops Left Outer Join NULL NULL 1 0 4,18E-06 11 0,8692666 [Expr1010] NULL PLAN_ROW 0 1
1 1 |--Constant Scan 1 4 3 Constant Scan Constant Scan NULL NULL 1 0 1,157E-06 9 1,157E-06 NULL NULL PLAN_ROW 0 1
1 1 |--Assert(WHERE:(CASE WHEN [Expr1009]>(1) THEN (0) ELSE NULL END)) 1 5 3 Assert Assert WHERE:(CASE WHEN [Expr1009]>(1) THEN (0) ELSE NULL END) NULL 1 0 1,8E-07 11 0,8692613 [Expr1010] NULL PLAN_ROW 0 1
1 1 |--Stream Aggregate(DEFINE:([Expr1009]=Count(*), [Expr1010]=ANY([Expr1006]))) 1 6 5 Stream Aggregate Aggregate NULL [Expr1009]=Count(*), [Expr1010]=ANY([Expr1006]) 1 0 0,01713626 19 0,8692611 [Expr1009], [Expr1010] NULL PLAN_ROW 0 1
0 1 |--Filter(WHERE:([Expr1006]>(1))) 1 7 6 Filter Filter WHERE:([Expr1006]>(1)) NULL 28559,59 0 0,01628152 11 0,8521248 [Expr1006] NULL PLAN_ROW 0 1
68727 1 |--Merge Join(Inner Join, MERGE:([DT].[DimensionTypeID])=([D].[DimensionTypeID]), RESIDUAL:([RSys].[dbo].[Dimension].[DimensionTypeID] as [D].[DimensionTypeID]=[RSys].[dbo].[DimensionType].[DimensionTypeID] as [DT].[DimensionTypeID])) 1 9 7 Merge Join Inner Join MERGE:([DT].[DimensionTypeID])=([D].[DimensionTypeID]), RESIDUAL:([RSys].[dbo].[Dimension].[DimensionTypeID] as [D].[DimensionTypeID]=[RSys].[dbo].[DimensionType].[DimensionTypeID] as [DT].[DimensionTypeID]) NULL 33157,01 0 0,08098962 11 0,8358433 [Expr1006] NULL PLAN_ROW 0 1
100 1 |--Sort(ORDER BY:([DT].[DimensionTypeID] ASC)) 1 10 9 Sort Sort ORDER BY:([DT].[DimensionTypeID] ASC) NULL 101 0,01126126 0,001149091 23 0,01807415 [DT].[DimensionTypeID] NULL PLAN_ROW 0 1
100 1 | |--Table Scan(OBJECT:([RSys].[dbo].[DimensionType] AS [DT]), WHERE:([RSys].[dbo].[DimensionType].[ExternalDimensionTypeID] as [DT].[ExternalDimensionTypeID] IS NOT NULL)) 1 11 10 Table Scan Table Scan OBJECT:([RSys].[dbo].[DimensionType] AS [DT]), WHERE:([RSys].[dbo].[DimensionType].[ExternalDimensionTypeID] as [DT].[ExternalDimensionTypeID] IS NOT NULL) [DT].[DimensionTypeID] 101 0,005347222 0,0002681 35 0,005615322 [DT].[DimensionTypeID] NULL PLAN_ROW 0 1
0 0 |--Compute Scalar(DEFINE:([Expr1006]=CONVERT_IMPLICIT(int,[Expr1018],0))) 1 12 9 Compute Scalar Compute Scalar DEFINE:([Expr1006]=CONVERT_IMPLICIT(int,[Expr1018],0)) [Expr1006]=CONVERT_IMPLICIT(int,[Expr1018],0) 34006,03 0 0,05823922 27 0,7367765 [D].[DimensionTypeID], [Expr1006] NULL PLAN_ROW 0 1
68727 1 |--Stream Aggregate(GROUP BY:([D].[DimensionTypeID], [D].[ExternalDimensionID]) DEFINE:([Expr1018]=Count(*))) 1 13 12 Stream Aggregate Aggregate GROUP BY:([D].[DimensionTypeID], [D].[ExternalDimensionID]) [Expr1018]=Count(*) 34006,03 0 0,05823922 27 0,7367765 [D].[DimensionTypeID], [Expr1018] NULL PLAN_ROW 0 1
68727 1 |--Index Scan(OBJECT:([RSys].[dbo].[Dimension].[IX_Dimension_DimensionTypeID_ExternalDimensionID] AS [D]), WHERE:([RSys].[dbo].[Dimension].[ExternalDimensionID] as [D].[ExternalDimensionID] IS NOT NULL) ORDERED FORWARD) 1 14 13 Index Scan Index Scan OBJECT:([RSys].[dbo].[Dimension].[IX_Dimension_DimensionTypeID_ExternalDimensionID] AS [D]), WHERE:([RSys].[dbo].[Dimension].[ExternalDimensionID] as [D].[ExternalDimensionID] IS NOT NULL) ORDERED FORWARD [D].[ExternalDimensionID], [D].[DimensionTypeID] 68727 0,5697917 0,0757567 37 0,6455483 [D].[ExternalDimensionID], [D].[DimensionTypeID] NULL PLAN_ROW 0 1

(13 row(s) affected)



(1 row(s) affected)
Rows Executes StmtText StmtId NodeId Parent PhysicalOp LogicalOp Argument DefinedValues EstimateRows EstimateIO EstimateCPU AvgRowSize TotalSubtreeCost OutputList Warnings Type Parallel EstimateExecutions
-------------------- -------------------- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------- ----------- ----------- ------------------------------ ------------------------------ -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------------------------------------------------------ ------------- ------------- ------------- ----------- ---------------- ------------------------------------------------- -------- ---------------------------------------------------------------- -------- ------------------
1 1 if exists
(
select null from Dimension D
inner join DimensionType DT on DT.DimensionTypeID = D.DimensionTypeID
where DT.ExternalDimensionTypeID is not null and D.ExternalDimensionID is not null
group by D.DimensionTypeID, D.ExternalDimensionID
having count(*) > 1
) 1 1 0 NULL NULL NULL NULL 1 NULL NULL NULL 0,009014531 NULL NULL GeneralQuery 0 NULL
0 0 |--Compute Scalar(DEFINE:([Expr1008]=CASE WHEN [Expr1009] THEN (1) ELSE (0) END)) 1 2 1 Compute Scalar Compute Scalar DEFINE:([Expr1008]=CASE WHEN [Expr1009] THEN (1) ELSE (0) END) [Expr1008]=CASE WHEN [Expr1009] THEN (1) ELSE (0) END 1 0 1E-07 11 0,009014531 [Expr1008] NULL PLAN_ROW 0 1
1 1 |--Nested Loops(Left Semi Join, DEFINE:([Expr1009] = [PROBE VALUE])) 1 3 2 Nested Loops Left Semi Join DEFINE:([Expr1009] = [PROBE VALUE]) [Expr1009] = [PROBE VALUE] 1 0 4,18E-06 9 0,009014431 [Expr1009] NULL PLAN_ROW 0 1
1 1 |--Constant Scan 1 4 3 Constant Scan Constant Scan NULL NULL 1 0 1,157E-06 9 1,157E-06 NULL NULL PLAN_ROW 0 1
0 1 |--Filter(WHERE:([Expr1006]>(1))) 1 5 3 Filter Filter WHERE:([Expr1006]>(1)) NULL 1 0 0,01628152 9 0,009009094 NULL NULL PLAN_ROW 0 1
68727 1 |--Nested Loops(Inner Join, WHERE:([RSys].[dbo].[Dimension].[DimensionTypeID] as [D].[DimensionTypeID]=[RSys].[dbo].[DimensionType].[DimensionTypeID] as [DT].[DimensionTypeID])) 1 7 5 Nested Loops Inner Join WHERE:([RSys].[dbo].[Dimension].[DimensionTypeID] as [D].[DimensionTypeID]=[RSys].[dbo].[DimensionType].[DimensionTypeID] as [DT].[DimensionTypeID]) NULL 1,187686 0 14,35667 11 0,009012702 [Expr1006] NULL PLAN_ROW 0 1
100 1 |--Table Scan(OBJECT:([RSys].[dbo].[DimensionType] AS [DT]), WHERE:([RSys].[dbo].[DimensionType].[ExternalDimensionTypeID] as [DT].[ExternalDimensionTypeID] IS NOT NULL)) 1 8 7 Table Scan Table Scan OBJECT:([RSys].[dbo].[DimensionType] AS [DT]), WHERE:([RSys].[dbo].[DimensionType].[ExternalDimensionTypeID] as [DT].[ExternalDimensionTypeID] IS NOT NULL) [DT].[DimensionTypeID] 1 0,005347222 0,0002681 35 0,0032831 [DT].[DimensionTypeID] NULL PLAN_ROW 0 1
0 0 |--Compute Scalar(DEFINE:([Expr1006]=CONVERT_IMPLICIT(int,[Expr1015],0))) 1 9 7 Compute Scalar Compute Scalar DEFINE:([Expr1006]=CONVERT_IMPLICIT(int,[Expr1015],0)) [Expr1006]=CONVERT_IMPLICIT(int,[Expr1015],0) 123,0279 0 0,05823922 27 0,00592744 [D].[DimensionTypeID], [Expr1006] NULL PLAN_ROW 0 1
6872700 100 |--Stream Aggregate(GROUP BY:([D].[DimensionTypeID], [D].[ExternalDimensionID]) DEFINE:([Expr1015]=Count(*))) 1 10 9 Stream Aggregate Aggregate GROUP BY:([D].[DimensionTypeID], [D].[ExternalDimensionID]) [Expr1015]=Count(*) 123,0279 0 0,05823922 27 0,00592744 [D].[DimensionTypeID], [Expr1015] NULL PLAN_ROW 0 1
6872700 100 |--Index Scan(OBJECT:([RSys].[dbo].[Dimension].[IX_Dimension_DimensionTypeID_ExternalDimensionID] AS [D]), WHERE:([RSys].[dbo].[Dimension].[ExternalDimensionID] as [D].[ExternalDimensionID] IS NOT NULL) ORDERED FORWARD) 1 11 10 Index Scan Index Scan OBJECT:([RSys].[dbo].[Dimension].[IX_Dimension_DimensionTypeID_ExternalDimensionID] AS [D]), WHERE:([RSys].[dbo].[Dimension].[ExternalDimensionID] as [D].[ExternalDimensionID] IS NOT NULL) ORDERED FORWARD [D].[ExternalDimensionID], [D].[DimensionTypeID] 248,6423 0,5697917 0,0757567 37 0,005597392 [D].[ExternalDimensionID], [D].[DimensionTypeID] NULL PLAN_ROW 0 1

(10 row(s) affected)



(1 row(s) affected)
7 окт 09, 08:23    [7751181]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по if exists  [new]
paxmeleon
Member

Откуда:
Сообщений: 67
Abbey Road
А так?
if (select count(*) from Dimension D
    inner join DimensionType DT on DT.DimensionTypeID = D.DimensionTypeID
    where DT.ExternalDimensionTypeID is not null and D.ExternalDimensionID is not null
    group by D.DimensionTypeID, D.ExternalDimensionID
    having count(*) > 1
   ) > 0
Планы покажете?
Интересно.


Вчера ввелся в заблуждение вашим предложением.
На самом деле, это не равнозначный запрос и в случае нескольких дубликатов он вообще отвалиться. ))
7 окт 09, 08:38    [7751212]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по if exists  [new]
paxmeleon
Member

Откуда:
Сообщений: 67
В итоге один и тот же запрос, одинаковый результат, но по-разному идет его проверка. Скорость отличается в десятки раз, если нет дубликатов, и оба запроса выполняются одинаково быстро, если дубликаты есть.

SET STATISTICS PROFILE ON 
go

with TEMP (val) as (
select null from Dimension D
inner join DimensionType DT on DT.DimensionTypeID = D.DimensionTypeID
where DT.ExternalDimensionTypeID is not null and D.ExternalDimensionID is not null
group by D.DimensionTypeID, D.ExternalDimensionID
having count(*) > 1)
select case count(*) when 0 then 0 else 1 end from TEMP
go

if exists (
select null from Dimension D
inner join DimensionType DT on DT.DimensionTypeID = D.DimensionTypeID
where DT.ExternalDimensionTypeID is not null and D.ExternalDimensionID is not null
group by D.DimensionTypeID, D.ExternalDimensionID
having count(*) > 1
) select 1 else select 0
go

SET STATISTICS PROFILE OFF
go

Вот статистика:


-----------
0

(1 row(s) affected)

Rows Executes StmtText StmtId NodeId Parent PhysicalOp LogicalOp Argument DefinedValues EstimateRows EstimateIO EstimateCPU AvgRowSize TotalSubtreeCost OutputList Warnings Type Parallel EstimateExecutions
-------------------- -------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------- ----------- ----------- ------------------------------ ------------------------------ ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------- ------------- ------------- ------------- ----------- ---------------- ------------------------------------------------- -------- ---------------------------------------------------------------- -------- ------------------
1 1 with TEMP (val) as (
select null from Dimension D
inner join DimensionType DT on DT.DimensionTypeID = D.DimensionTypeID
where DT.ExternalDimensionTypeID is not null and D.ExternalDimensionID is not null
group by D.DimensionTypeID, D.ExternalDimensionID
having count(*) > 1)
select case count(*) when 0 then 0 else 1 end from TEMP 1 1 0 NULL NULL NULL NULL 1 NULL NULL NULL 0,8692612 NULL NULL SELECT 0 NULL
0 0 |--Compute Scalar(DEFINE:([Expr1009]=CASE WHEN [Expr1008]=(0) THEN (0) ELSE (1) END)) 1 2 1 Compute Scalar Compute Scalar DEFINE:([Expr1009]=CASE WHEN [Expr1008]=(0) THEN (0) ELSE (1) END) [Expr1009]=CASE WHEN [Expr1008]=(0) THEN (0) ELSE (1) END 1 0 1E-07 11 0,8692612 [Expr1009] NULL PLAN_ROW 0 1
0 0 |--Compute Scalar(DEFINE:([Expr1008]=CONVERT_IMPLICIT(int,[Expr1018],0))) 1 3 2 Compute Scalar Compute Scalar DEFINE:([Expr1008]=CONVERT_IMPLICIT(int,[Expr1018],0)) [Expr1008]=CONVERT_IMPLICIT(int,[Expr1018],0) 1 0 0,01713626 11 0,8692611 [Expr1008] NULL PLAN_ROW 0 1
1 1 |--Stream Aggregate(DEFINE:([Expr1018]=Count(*))) 1 4 3 Stream Aggregate Aggregate NULL [Expr1018]=Count(*) 1 0 0,01713626 11 0,8692611 [Expr1018] NULL PLAN_ROW 0 1
0 1 |--Filter(WHERE:([Expr1006]>(1))) 1 5 4 Filter Filter WHERE:([Expr1006]>(1)) NULL 28559,59 0 0,01628152 9 0,8521248 NULL NULL PLAN_ROW 0 1
68727 1 |--Merge Join(Inner Join, MERGE:([DT].[DimensionTypeID])=([D].[DimensionTypeID]), RESIDUAL:([RSys].[dbo].[Dimension].[DimensionTypeID] as [D].[DimensionTypeID]=[RSys].[dbo].[DimensionType].[DimensionTypeID] as [DT].[DimensionTypeID])) 1 7 5 Merge Join Inner Join MERGE:([DT].[DimensionTypeID])=([D].[DimensionTypeID]), RESIDUAL:([RSys].[dbo].[Dimension].[DimensionTypeID] as [D].[DimensionTypeID]=[RSys].[dbo].[DimensionType].[DimensionTypeID] as [DT].[DimensionTypeID]) NULL 33157,01 0 0,08098962 11 0,8358433 [Expr1006] NULL PLAN_ROW 0 1
100 1 |--Sort(ORDER BY:([DT].[DimensionTypeID] ASC)) 1 8 7 Sort Sort ORDER BY:([DT].[DimensionTypeID] ASC) NULL 101 0,01126126 0,001149091 23 0,01807415 [DT].[DimensionTypeID] NULL PLAN_ROW 0 1
100 1 | |--Table Scan(OBJECT:([RSys].[dbo].[DimensionType] AS [DT]), WHERE:([RSys].[dbo].[DimensionType].[ExternalDimensionTypeID] as [DT].[ExternalDimensionTypeID] IS NOT NULL)) 1 9 8 Table Scan Table Scan OBJECT:([RSys].[dbo].[DimensionType] AS [DT]), WHERE:([RSys].[dbo].[DimensionType].[ExternalDimensionTypeID] as [DT].[ExternalDimensionTypeID] IS NOT NULL) [DT].[DimensionTypeID] 101 0,005347222 0,0002681 35 0,005615322 [DT].[DimensionTypeID] NULL PLAN_ROW 0 1
0 0 |--Compute Scalar(DEFINE:([Expr1006]=CONVERT_IMPLICIT(int,[Expr1017],0))) 1 10 7 Compute Scalar Compute Scalar DEFINE:([Expr1006]=CONVERT_IMPLICIT(int,[Expr1017],0)) [Expr1006]=CONVERT_IMPLICIT(int,[Expr1017],0) 34006,03 0 0,05823922 27 0,7367765 [D].[DimensionTypeID], [Expr1006] NULL PLAN_ROW 0 1
68727 1 |--Stream Aggregate(GROUP BY:([D].[DimensionTypeID], [D].[ExternalDimensionID]) DEFINE:([Expr1017]=Count(*))) 1 11 10 Stream Aggregate Aggregate GROUP BY:([D].[DimensionTypeID], [D].[ExternalDimensionID]) [Expr1017]=Count(*) 34006,03 0 0,05823922 27 0,7367765 [D].[DimensionTypeID], [Expr1017] NULL PLAN_ROW 0 1
68727 1 |--Index Scan(OBJECT:([RSys].[dbo].[Dimension].[IX_Dimension_DimensionTypeID_ExternalDimensionID] AS [D]), WHERE:([RSys].[dbo].[Dimension].[ExternalDimensionID] as [D].[ExternalDimensionID] IS NOT NULL) ORDERED FORWARD) 1 12 11 Index Scan Index Scan OBJECT:([RSys].[dbo].[Dimension].[IX_Dimension_DimensionTypeID_ExternalDimensionID] AS [D]), WHERE:([RSys].[dbo].[Dimension].[ExternalDimensionID] as [D].[ExternalDimensionID] IS NOT NULL) ORDERED FORWARD [D].[ExternalDimensionID], [D].[DimensionTypeID] 68727 0,5697917 0,0757567 37 0,6455483 [D].[ExternalDimensionID], [D].[DimensionTypeID] NULL PLAN_ROW 0 1

(11 row(s) affected)



(1 row(s) affected)
Rows Executes StmtText StmtId NodeId Parent PhysicalOp LogicalOp Argument DefinedValues EstimateRows EstimateIO EstimateCPU AvgRowSize TotalSubtreeCost OutputList Warnings Type Parallel EstimateExecutions
-------------------- -------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------- ----------- ----------- ------------------------------ ------------------------------ -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------------------------------------------------------ ------------- ------------- ------------- ----------- ---------------- ------------------------------------------------- -------- ---------------------------------------------------------------- -------- ------------------
1 1 if exists (
select null from Dimension D
inner join DimensionType DT on DT.DimensionTypeID = D.DimensionTypeID
where DT.ExternalDimensionTypeID is not null and D.ExternalDimensionID is not null
group by D.DimensionTypeID, D.ExternalDimensionID
having count(*) > 1
) 1 1 0 NULL NULL NULL NULL 1 NULL NULL NULL 0,009014531 NULL NULL GeneralQuery 0 NULL
0 0 |--Compute Scalar(DEFINE:([Expr1008]=CASE WHEN [Expr1009] THEN (1) ELSE (0) END)) 1 2 1 Compute Scalar Compute Scalar DEFINE:([Expr1008]=CASE WHEN [Expr1009] THEN (1) ELSE (0) END) [Expr1008]=CASE WHEN [Expr1009] THEN (1) ELSE (0) END 1 0 1E-07 11 0,009014531 [Expr1008] NULL PLAN_ROW 0 1
1 1 |--Nested Loops(Left Semi Join, DEFINE:([Expr1009] = [PROBE VALUE])) 1 3 2 Nested Loops Left Semi Join DEFINE:([Expr1009] = [PROBE VALUE]) [Expr1009] = [PROBE VALUE] 1 0 4,18E-06 9 0,009014431 [Expr1009] NULL PLAN_ROW 0 1
1 1 |--Constant Scan 1 4 3 Constant Scan Constant Scan NULL NULL 1 0 1,157E-06 9 1,157E-06 NULL NULL PLAN_ROW 0 1
0 1 |--Filter(WHERE:([Expr1006]>(1))) 1 5 3 Filter Filter WHERE:([Expr1006]>(1)) NULL 1 0 0,01628152 9 0,009009094 NULL NULL PLAN_ROW 0 1
68727 1 |--Nested Loops(Inner Join, WHERE:([RSys].[dbo].[Dimension].[DimensionTypeID] as [D].[DimensionTypeID]=[RSys].[dbo].[DimensionType].[DimensionTypeID] as [DT].[DimensionTypeID])) 1 7 5 Nested Loops Inner Join WHERE:([RSys].[dbo].[Dimension].[DimensionTypeID] as [D].[DimensionTypeID]=[RSys].[dbo].[DimensionType].[DimensionTypeID] as [DT].[DimensionTypeID]) NULL 1,187686 0 14,35667 11 0,009012702 [Expr1006] NULL PLAN_ROW 0 1
100 1 |--Table Scan(OBJECT:([RSys].[dbo].[DimensionType] AS [DT]), WHERE:([RSys].[dbo].[DimensionType].[ExternalDimensionTypeID] as [DT].[ExternalDimensionTypeID] IS NOT NULL)) 1 8 7 Table Scan Table Scan OBJECT:([RSys].[dbo].[DimensionType] AS [DT]), WHERE:([RSys].[dbo].[DimensionType].[ExternalDimensionTypeID] as [DT].[ExternalDimensionTypeID] IS NOT NULL) [DT].[DimensionTypeID] 1 0,005347222 0,0002681 35 0,0032831 [DT].[DimensionTypeID] NULL PLAN_ROW 0 1
0 0 |--Compute Scalar(DEFINE:([Expr1006]=CONVERT_IMPLICIT(int,[Expr1015],0))) 1 9 7 Compute Scalar Compute Scalar DEFINE:([Expr1006]=CONVERT_IMPLICIT(int,[Expr1015],0)) [Expr1006]=CONVERT_IMPLICIT(int,[Expr1015],0) 123,0279 0 0,05823922 27 0,00592744 [D].[DimensionTypeID], [Expr1006] NULL PLAN_ROW 0 1
6872700 100 |--Stream Aggregate(GROUP BY:([D].[DimensionTypeID], [D].[ExternalDimensionID]) DEFINE:([Expr1015]=Count(*))) 1 10 9 Stream Aggregate Aggregate GROUP BY:([D].[DimensionTypeID], [D].[ExternalDimensionID]) [Expr1015]=Count(*) 123,0279 0 0,05823922 27 0,00592744 [D].[DimensionTypeID], [Expr1015] NULL PLAN_ROW 0 1
6872700 100 |--Index Scan(OBJECT:([RSys].[dbo].[Dimension].[IX_Dimension_DimensionTypeID_ExternalDimensionID] AS [D]), WHERE:([RSys].[dbo].[Dimension].[ExternalDimensionID] as [D].[ExternalDimensionID] IS NOT NULL) ORDERED FORWARD) 1 11 10 Index Scan Index Scan OBJECT:([RSys].[dbo].[Dimension].[IX_Dimension_DimensionTypeID_ExternalDimensionID] AS [D]), WHERE:([RSys].[dbo].[Dimension].[ExternalDimensionID] as [D].[ExternalDimensionID] IS NOT NULL) ORDERED FORWARD [D].[ExternalDimensionID], [D].[DimensionTypeID] 248,6423 0,5697917 0,0757567 37 0,005597392 [D].[ExternalDimensionID], [D].[DimensionTypeID] NULL PLAN_ROW 0 1

(10 row(s) affected)



(1 row(s) affected)

-----------
0

(1 row(s) affected)
7 окт 09, 09:01    [7751265]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по if exists  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
paxmeleon
Теперь вопрос, как же не идиоты проверяют наличие дубликатов? Будьте добры, не поленитесь ответить, мой деликатный друг.
Не поленитесь и Вы в таком случае сформулировать всю задачу,
выложить здесь скрипт создания таблиц (с констрейнтами, индексами и т.д.)
и скрипт заполнения таблиц тестовыми данными.
Раз уж речь зашла не об IF EXISTS(), а о выявлении дубликатов.

И версию сервера написать не забудьте.
7 окт 09, 09:04    [7751278]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по if exists  [new]
paxmeleon
Member

Откуда:
Сообщений: 67
iap
Не поленитесь и Вы в таком случае сформулировать всю задачу,
выложить здесь скрипт создания таблиц (с констрейнтами, индексами и т.д.)
и скрипт заполнения таблиц тестовыми данными.
Раз уж речь зашла не об IF EXISTS(), а о выявлении дубликатов.

И версию сервера написать не забудьте.


Не, речь как раз об exists. Мне интересно, почему так сильно отличается результат по скорости. Один и тот же запрос, но по разному проверяется результат, и на тебе. Что за запрос и что он делает, я думаю, уже не суть важно. Просто как пример взята проверка дубликатов )))
7 окт 09, 09:08    [7751296]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по if exists  [new]
paxmeleon
Member

Откуда:
Сообщений: 67
Версия сервера: Microsoft SQL Server 2005 - 9.00.4035.00 (Intel X86) Nov 24 2008 13:01:59 Copyright (c) 1988-2005 Microsoft Corporation Developer Edition on Windows NT 5.2 (Build 3790: Service Pack 2)
7 окт 09, 09:12    [7751313]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по if exists  [new]
iljy
Member

Откуда:
Сообщений: 8711
paxmeleon,

почему отличается скорость как раз понятно. Вы на планы смотрели? Для варианта Count(*) > 0 оптимизатор строит план с сортировкой и Merge Join, потому что ожидает сканирования всей таблицы, а для exists - план с nested loop, потому что ожидает гораааздо меньше строк (248 против 68727). А сканирует все равно все, потому что дублей нет. Причина - скорее всего протухшая статистика.
7 окт 09, 10:26    [7751720]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по if exists  [new]
Glory
Member

Откуда:
Сообщений: 104760
paxmeleon
В итоге один и тот же запрос, одинаковый результат, но по-разному идет его проверка. Скорость отличается в десятки раз, если нет дубликатов, и оба запроса выполняются одинаково быстро, если дубликаты есть.

Если вы еще не поняли, то результаты ваших запросов _разные_
1ый запрос выбирает все записи, которые соответствуют соединению и фильтру
2ой запрос ищет хоть одну запись, которая соответствуют соединению и фильтру
7 окт 09, 10:36    [7751783]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить