У меня есть заявление, которое занимает 10 секунд для выполнения на 10k элементов в таблице X:Почему мой некоррелированный подзапрос так медленно?
Version 1
SELECT *
FROM X
WHERE pk = 77843
AND (a IS NULL OR a NOT IN (SELECT DISTINCT(b)
FROM X
WHERE pk = 77843
AND l IS NOT NULL))
Суб-запрос коррелированы, а это означает, что он не имеет никакого отношения к внешний запрос. Это означает, что подзапрос должен выполняться только один раз.
Версия 2:
Теперь, если я извлечь подзапрос и выполнить вычисление заранее запрос выполняется в < 1s.
DECLARE @listOfb table (id int)
INSERT INTO @listOfb(id)
(SELECT DISTINCT(b) as Numbers
FROM X
WHERE pk = 77843
AND l IS NOT NULL)
SELECT *
FROM X
WHERE pk = 77843
AND (a IS NULL OR a NOT IN (SELECT * FROM @listOfb))
Так почему версия 2 намного быстрее, чем версия 1?
Update
Я добавил (то, что я думаю, что называется) план выполнения версии 1: Запрос удаления около 10k строк.
Вы просматривали ** планы выполнения ** для двух запросов? –
'DISTINCT' не является функцией (в столбце), она является частью' SELECT DISTINCT' и работает со всеми выбранными строками. Удалите эти лишние круглые скобки, чтобы сделать вещи более ясными! 'SELECT DISTINCT (a), b ...' лучше написано как 'SELECT DISTINCT a, b ...', но также может быть записано как 'SELECT DISTINCT a, (b) ...' ... – jarlh
Однако , не нужно делать SELECT DISTINCT здесь ... – jarlh