powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / как заменить LEFT JOIN на EXIST ?
25 сообщений из 54, страница 2 из 3
как заменить LEFT JOIN на EXIST ?
    #32067514
Фотография MiCe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
как заменить LEFT JOIN на EXIST ?
собственно subj....
или что?
...
Рейтинг: 0 / 0
как заменить LEFT JOIN на EXIST ?
    #32067515
keystop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
истина где-то рядом )
...
Рейтинг: 0 / 0
как заменить LEFT JOIN на EXIST ?
    #32067516
Genady
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
или что?

преимущество с exists...
сравни скорость... особенно если таблицы большие....
...
Рейтинг: 0 / 0
как заменить LEFT JOIN на EXIST ?
    #32067521
SilencerID
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
>> оператор IN тормоз по сравнению с exists

Где об этом написано?

Читаем MSDN:

EXISTS
Specifies a subquery to test for the existence of rows.
Returns TRUE if a subquery contains any rows.

IN
Determines if a given value matches any value in a subquery or a list.
If the value is equal to any value returned by subquery or is equal to any expression from the comma-separated list, the result value is TRUE.
...
Рейтинг: 0 / 0
как заменить LEFT JOIN на EXIST ?
    #32067524
Фотография MiCe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
скажем так.... если таблица R не большая а таблица C большая..... с exists быстро....
...
Рейтинг: 0 / 0
как заменить LEFT JOIN на EXIST ?
    #32067531
Фотография MiCe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 SilencerID
проверь сам...
на счет TOP 1 если без сортировки то вернет любую первую.... возможно что с exists теперь уже и не нужно....
...
Рейтинг: 0 / 0
как заменить LEFT JOIN на EXIST ?
    #32067533
keystop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MiCe
а поднимите количество записей хотя бы до 1000000

вообщем-то
JOIN - 5.317 ss
EXISTS - 4.808 ss
по видимому дальше разница дальше будет расти
...
Рейтинг: 0 / 0
как заменить LEFT JOIN на EXIST ?
    #32067536
Фотография MiCe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
это назувается накладные расходы при нехватке памяти...
а если статистика верная может еще вырасти....
...
Рейтинг: 0 / 0
как заменить LEFT JOIN на EXIST ?
    #32067605
SilencerID
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
to keystop:

А проверь-ка для сравнения запрос:

SELECT R.ID
FROM R
WHERE R.ID IN
(SELECT TOP 1 C.ID FROM C WHERE C.NAME=123) OR
R.ID NOT IN
(SELECT C.ID FROM C)

to MiCe:

Ну, TOP 1 и я могу добавить :) (см. выше)
...
Рейтинг: 0 / 0
как заменить LEFT JOIN на EXIST ?
    #32067610
Genady
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JOIN - 5.317 ss
EXISTS - 4.808 ss


Говорите точно скока ве..., тьфу, т.е. скока раз меряли?
А индекс по фильтруемым полям имеется?
...
Рейтинг: 0 / 0
как заменить LEFT JOIN на EXIST ?
    #32067616
SilencerID
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
to keystop:

хотя нет, проверь этот, без ТОП 1, иначе ошибка - проверку дополнительную нужно:

SELECT R.ID
FROM R
WHERE R.ID IN
(SELECT C.ID FROM C WHERE C.NAME=123) OR
R.ID NOT IN
(SELECT C.ID FROM C)

Сколько от мс потянет?
...
Рейтинг: 0 / 0
как заменить LEFT JOIN на EXIST ?
    #32067693
Snark
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник



It is fairly common request to write a Transact-SQL query to to compare a parent table and a child table and find out if there are any parent records that don't have a match in the child table. Generally, there are three ways this can be done:

Using a NOT EXISTS

SELECT a.hdr_key
FROM hdr_tbl a
WHERE NOT EXISTS (SELECT * FROM dtl_tbl b WHERE a.hdr_key = b.hdr_key)

Using a Left Join

SELECT a.hdr_key
FROM hdr_tbl a
LEFT JOIN dtl_tbl b ON a.hdr_key = b.hdr_key
WHERE b.hdr_key IS NULL

Using a NOT IN

SELECT hdr_key
FROM hdr_tbl
WHERE hdr_key NOT IN (SELECT hdr_key FROM dtl_tbl)

In each case, the above query will return identical results. But, which of these three variations of the same query produces the best performance? Assuming everything else is equal, the best performing version through the worst performing version will be from top to bottom, as displayed above. In other words, the NOT EXISTS variation of this query is generally the most efficient.

I say generally, because the indexes found on the tables, along with the number of rows in each table, can influence the results. If you are not sure which variation to try yourself, you can try them all and see which produces the best results in your particular circumstances. [7.0, 2000] Added 3-29-2002
...
Рейтинг: 0 / 0
как заменить LEFT JOIN на EXIST ?
    #32067696
Snark
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Предыдуший пост - цитата из этого источника :
http://www.sql-server-performance.com/transact_sql.asp
И оттуда же :

If you currently have a query that uses NOT IN, which offers poor performance because the SQL Server optimizer has to use a nested table scan to perform this activity, instead try to use one of the following options instead, all of which offer better performance:

Use EXISTS or NOT EXISTS

Use IN.

Perform a LEFT OUTER JOIN and check for a NULL condition

[6.5, 7.0, 2000] Updated 5-31-2002

Может использование EXIST instead of LEFT JOIN ето просто мода, но скорее всего нужно проверять на каждом конкретном случае
Хотя, было бы интересно понять при каких условиях один метод производительнее другого.

Regards, Snark
...
Рейтинг: 0 / 0
как заменить LEFT JOIN на EXIST ?
    #32067698
Snark
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Индекс по полю C.Name есть. из-за етого индекса, в том числе я и хочу уйти от LEFT JOIN, так как, как я понимаю, при проверке на NULL индексы использоваться не могут
...
Рейтинг: 0 / 0
как заменить LEFT JOIN на EXIST ?
    #32067699
Snark
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
дополнительные детали, количество записей в таблице C значительно (примерно в 10 раз) меньше чем в таблице R
...
Рейтинг: 0 / 0
как заменить LEFT JOIN на EXIST ?
    #32067702
Фотография Alexes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MiCe
TOP 1 никогда не выберает все.....
сервер ищет первое вхождение....


По сути это верно, но на практике получается следующее:
не знаю как там SQL2000, но SQL7 выдает лучшие планы для select 1, чем для select top 1 1, как для exists, так и для not exists.
...
Рейтинг: 0 / 0
как заменить LEFT JOIN на EXIST ?
    #32067708
Фотография MiCe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 Alexes...
top это привычка.... при exists он не нужен... он подразумеватся по умолчанию.... думаю что top 1 1 даст тоже самое....
...
Рейтинг: 0 / 0
как заменить LEFT JOIN на EXIST ?
    #32067726
SilencerID
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
to Snark

Ну смотреть надо в каждом конкретном случае, что применять. Все зависит от количества условий в выражении. В даном случае, все же лучше NOT IN.

Но за ссылку спасибо.
...
Рейтинг: 0 / 0
как заменить LEFT JOIN на EXIST ?
    #32067728
Фотография MiCe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
и чем же ш лучше?
...
Рейтинг: 0 / 0
как заменить LEFT JOIN на EXIST ?
    #32067733
Snark
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Практика - критерий истины, результаты теста :
Как видно LEFT JOIN далеко впереди, EXIST ненамного опережает NOT IN
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
R table =  20000  records 
C table =  1000  records 
# Runs =  10 

SELECT R.ID             
 Left Join : 
  Average:  82 . 5  ms;  SD :  7 . 25 ;   40 . 88 %;
 NOT IN :
  Average:  201 . 8  ms; SD:  4 . 87 ;   100 %;
 EXIST :
  Average:  82 . 5  ms;  SD :  7 . 25 ;  98 . 36 %;
  
SELECT COUNT(R.ID) AS ASCount
 Left Join : 
  Average:  15 . 5  ms;  SD :  0 . 53 ;   12 . 24 %;
 NOT IN :
  Average:  126 . 6  ms; SD:  5 . 06 ;   100 %;
 EXIST :
  Average:  118 . 8  ms;  SD :  8 . 01 ;   93 . 83 %;


Regards, Snark
...
Рейтинг: 0 / 0
как заменить LEFT JOIN на EXIST ?
    #32067734
Snark
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sorry, disregard last report, this is the correct one
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
R table =  20000  records 
C table =  1000  records 
# Runs =  10 

SELECT dbo.R.ID             
 Left Join : 
  Average:  82 . 5  ms;  SD :  7 . 25 ;   40 . 88 %;
 NOT IN
  Average:  201 . 8  ms; SD:  4 . 87 ;   100 %;
 EXIST
  Average:  198 . 5  ms;  SD :  7 . 25 ;  98 . 36 %;
  
SELECT COUNT(R.ID) AS ASCount
 Left Join : 
  Average:  15 . 5  ms;  SD :  0 . 53 ;   12 . 24 %;
 NOT IN
  Average:  126 . 6  ms; SD:  5 . 06 ;   100 %;
 EXIST
  Average:  118 . 8  ms;  SD :  8 . 01 ;   93 . 83 %;


Snark
...
Рейтинг: 0 / 0
как заменить LEFT JOIN на EXIST ?
    #32067736
Фотография MiCe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
покажи запросы с count?
...
Рейтинг: 0 / 0
как заменить LEFT JOIN на EXIST ?
    #32067738
Фотография MiCe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
меня болше поражает количество строк.....
у меня оно разное... отсюда вывод что запросы с left и exists не тождественны....
вот скриптик.... немного урезанный...
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
set nocount on
create table big (id int identity( 1 , 1 ) not null primary key clustered,
                value varchar( 100 ))
create table small ([id] int not null,[name] varchar( 100 ))
declare @i bigint,@d datetime
select @i= 1 
while @i< 100000 
begin
  insert into big(value) values (convert(varchar,@i*@i/ 17 . 0 ))
  set @i=@i+ 1 
end
select @i= 1 
while @i< 10000 
begin
  insert into small([id],[name]) 
  values (cast(( 1 /RAND(@i+datepart(ms,getdate()))* 10000000000000000 ) as bigint)% 100000  ,
          convert(varchar,@i*@i))
  select @i=@i+ 1 
end
create clustered index ix_small_id on  small ([id])
create index ix_small_name on  small ([name])
set nocount off
print 'exists'
select big.id
from big
where not exists(select  1  from small where small.[id]=big.[id]) 
       or exists(select  1  from small where small.[id]=big.[id] and small.[name] like '%00%')
print 'left'
select big.id
from big left join small on big.[id]=small.[id]
where small.[id] is null or small.[name] like '%00%'
drop table big drop table small
...
Рейтинг: 0 / 0
как заменить LEFT JOIN на EXIST ?
    #32067739
Snark
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
SELECT COUNT(R.ID) AS ASCount
FROM  R LEFT OUTER JOIN
               C ON R.ID = C.ID
WHERE (C.Name IS NULL) OR
               (C.Name =  123 )


SELECT COUNT(R.ID) AS ASCount
FROM R 
WHERE R.ID IN 
(SELECT C.ID FROM C WHERE C.Name= 123 ) OR 
R.ID NOT IN 
(SELECT C.ID FROM C) 


SELECT COUNT(R.ID) AS ASCount
 FROM R 
WHERE EXISTS(SELECT top  1   1  from C where R.ID=C.ID AND C.Name =  123 ) 
      OR NOT EXISTS(SELECT top  1   1  from C where R.ID=C.ID )




SELECT R.ID
FROM  R LEFT OUTER JOIN
               C ON R.ID = C.ID
WHERE (C.Name IS NULL) OR
               (C.Name =  123 )

SELECT R.ID
FROM R 
WHERE R.ID IN 
(SELECT C.ID FROM C WHERE C.Name= 123 ) OR 
R.ID NOT IN 
(SELECT C.ID FROM C) 


SELECT R.ID
 FROM R 
WHERE EXISTS(SELECT top  1   1  from C where R.ID=C.ID AND C.Name =  123 ) 
      OR NOT EXISTS(SELECT top  1   1  from C where R.ID=C.ID ) 
...
Рейтинг: 0 / 0
как заменить LEFT JOIN на EXIST ?
    #32067740
Фотография MiCe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а если добавить group by R.ID ?....
ланенько.... пойду ка я спать....устал....
...
Рейтинг: 0 / 0
25 сообщений из 54, страница 2 из 3
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / как заменить LEFT JOIN на EXIST ?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]