Присоединение к SQL-серверу и вопрос производительности подзапроса - PullRequest
6 голосов
/ 08 сентября 2011

Я обнаружил, что в некоторых случаях такой запрос, как

select 
   usertable.userid,
   (select top 1 name from nametable where userid = usertable.userid) as name 
from usertable 
where active = 1

, занимает на SS2008R2 на порядок больше времени, чем эквивалентный запрос соединения

select 
   usertable.userid,
   nametable.name 
from usertable 
left join nametable on nametable.userid = usertable.userid 
where usertable.active = 1

, где обе таблицы индексируютсяи иметь более 100 тысяч строк.Интересно, что вставка предложения top в исходный запрос заставляет его работать наравне с запросом на соединение:

select 
    top (select count(*) from usertable where active = 1) usertable.userid,
    (select top 1 name from nametable where userid = usertable.userid) as name 
from usertable 
where active = 1

Кто-нибудь знает, почему исходный запрос выполняется так плохо?

Ответы [ 3 ]

3 голосов
/ 08 сентября 2011

Ну, запросы разные - если столбец userid не является первичным ключом или имеет ограничение уникальности, тогда второй запрос может вернуть больше строк, чем первый.ID пользователя является первичным ключом / уникальной попыткой удаления части TOP 1 первого подзапроса:

select 
   usertable.userid,
   (select name from nametable where userid = usertable.userid) as name 
from usertable 
where active = 1
2 голосов
/ 08 сентября 2011

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

A JOIN выполняется один раз для всего набора результатов исливается.Ваш подзапрос выполняет внешний запрос, затем для каждой возвращаемой строки он снова запускает подзапрос.

1 голос
/ 08 сентября 2011

Исходный запрос будет выполнять подпрограмму select столько раз, сколько имеется строк, поэтому низкая производительность.

Когда вы JOIN получаете полный набор результатов сразу.

...