2014-12-05 1 views
0
INSERT INTO TableA 
    SELECT 
     x, 
     y, 
     z  
      FROM TableB 
      WHERE x IN 
        (select DISTINCT x 
          FROM TableC 
           WHERE x NOT IN 
              (SELECT DISTINCT x from TableD) 
        ) 

Этот запрос берет навсегда, и он не завершается.Почему INSERT занимает время при использовании подзапросов

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

+0

Вы просмотрели свой план выполнения, когда вы запускаете весь свой выбор? – Paddy

+0

«не в» имеет тенденцию быть медленным. –

+0

жаль это сказать, но еще не слышал о плане исполнения раньше? Можете ли вы направить меня на это, пожалуйста? @Paddy – akd

ответ

0

Попробуйте этот запрос:

insert into TableA 
select b.* 
from TableB b    --with(nolock) 
left outer join TableC c --with(nolock) 
on b.x = c.x 
left outer join TableD d --with(nolock) 
on c.x = d.x 
where c.x is not null and d.x is null 

, если он также работает бесконечно, то раскомментируйте with(nolock) и повторите попытку. если он не работает, то проверьте оценочный план выполнения.

0

Во-первых, вам нужно посмотреть план выполнения запроса - он может рассказать вам, где узкие места или отсутствуют индексы, которые значительно ускорят ваш запрос. Я думаю, что это, скорее всего, так, как ваш запрос прост, так что Я не понимаю, почему это займет так много времени;

enter image description here

Я думаю, вы могли бы также реструктурировать вы запрашиваете так, что он использует присоединяется вместо не - было бы полезно, если бы я знал данные, чтобы увидеть, если это дало те же результаты, но я думаю, что он должен ;

SELECT B.x, 
     B.y, 
     B.Z 
FROM TableB B 
INNER JOIN --where in 
    (
     SELECT DISTINCT x 
     FROM TableC c 
     LEFT JOIN TableD d 
      ON c.x = d.x 
     WHERE d.x IS NULL -- c x not in d x 
    ) sub 
on B.x = sub.x 
0

Подзапросы и DISTINCT, когда они не нужны, как правило, плохо подходят для работы. Вы можете выполнить то, что вам нужно, используя JOIN.

SELECT b.x, b.y, b.z 
FROM TableB b 
INNER JOIN TableC c ON c.x=b.x 
LEFT JOIN TableD d ON d.x=b.x 
WHERE d.x IS NULL 
GROUP BY b.x, b.y, b.z -- only if you have duplicates and need unique records 

Внутреннее соединение на TableC фиксирует ваш 1-ый "IN", затем LEFT JOIN и d.x IS NULL исправляет "NOT IN" п.

Наконец, убедитесь, что у вас есть индексы в столбце «x» в каждой таблице.

CREATE INDEX IX_TableB_X ON TableB (X); 
CREATE INDEX IX_TableC_X ON TableC (X); 
CREATE INDEX IX_TableD_X ON TableD (X);