SQL - улучшить производительность запросов NOT EXISTS - PullRequest
14 голосов
/ 16 февраля 2009

Есть ли способ улучшить производительность SQL-запросов такого типа:

INSERT
INTO ...
WHERE NOT EXISTS(Validation...)

Проблема в том, что когда в моей таблице много данных (например, миллионов строк), выполнение предложения WHERE NOT EXISTS выполняется очень медленно. Я должен сделать эту проверку, потому что я не могу вставить дублированные данные.

Я использую SQLServer 2005

ТНХ

Ответы [ 6 ]

11 голосов
/ 16 февраля 2009

Вне моей головы, вы можете попробовать что-то вроде:

 TRUNCATE temptable
 INSERT INTO temptable ...
 INSERT INTO temptable ... 
 ...
 INSERT INTO realtable
 SELECT temptable.* FROM temptable
 LEFT JOIN realtable on realtable.key = temptable.key
 WHERE realtable.key is null
11 голосов
/ 16 февраля 2009

Убедитесь, что вы выполняете поиск по индексированным столбцам, без манипуляций с данными в этих столбцах (например, подстрокой и т. Д.)

5 голосов
/ 16 февраля 2009

Попробуйте заменить NOT EXISTS на левое внешнее соединение, иногда оно работает лучше в больших наборах данных.

0 голосов
/ 17 февраля 2009
insert into customers 
select * 
from newcustomers 
where customerid not in (select customerid 
                         from customers)

.. может быть более эффективным. Как уже говорили другие, убедитесь, что у вас есть индексы для любых полей поиска.

0 голосов
/ 16 февраля 2009

Если вы вообще сможете уменьшить свое проблемное пространство, то вы получите кучу производительности. Вы абсолютно уверены, что каждая из этих строк в этой таблице должна быть проверена?

Другая вещь, которую вы можете попробовать - это DELETE InsertTable FROM InsertTable INNER JOIN ExistingTable ON <Validation criteria> перед вашей вставкой. Тем не менее, ваш пробег может варьироваться

0 голосов
/ 16 февраля 2009

Обратите внимание на другой ответ относительно индексации. NOT EXISTS обычно довольно быстрый, если у вас хорошие индексы.

Но у меня были проблемы с производительностью с утверждениями, которые вы описываете. Один из методов, который я использовал для обхода, состоит в том, чтобы использовать временную таблицу для значений-кандидатов, выполнить DELETE FROM ... WHERE EXISTS (...), а затем вслепую вставить остаток. Внутри сделки, конечно же, чтобы избежать условий гонки. Разделение запросов иногда позволяет оптимизатору выполнять свою работу, не путаясь.

...