Ответ 1
Убедитесь, что вы выполняете поиск по индексированным столбцам без манипуляций с данными в этих столбцах (например, подстрокой и т.д.).
Есть ли способ улучшить производительность SQL-запросов:
INSERT
INTO ...
WHERE NOT EXISTS(Validation...)
Проблема заключается в том, что у меня есть много данных в моей таблице (например, миллион строк), выполнение предложения WHERE NOT EXISTS
, если оно очень медленное. Я должен сделать это подтверждение, потому что я не могу вставить дублированные данные.
Я использую SQLServer 2005
ТНХ
Убедитесь, что вы выполняете поиск по индексированным столбцам без манипуляций с данными в этих столбцах (например, подстрокой и т.д.).
Сверху моей головы вы можете попробовать что-то вроде:
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
Попробуйте заменить NOT EXISTS на левое внешнее соединение, оно иногда лучше работает в больших наборах данных.
Обратите внимание на другой ответ, касающийся индексации. NOT EXISTS обычно довольно быстро, если у вас хорошие индексы.
Но у меня есть были проблемы с производительностью с такими утверждениями, которые вы описываете. Один из методов, который я использовал, чтобы использовать эту временную таблицу для значений кандидата, выполняет DELETE FROM... WHERE EXISTS (...), а затем слепо ВСТАВИТЬ остаток. Разумеется, внутри транзакции следует избегать условий гонки. Разделение запросов иногда позволяет оптимизатору выполнять свою работу, не запутываясь.
Если вы вообще можете уменьшить свое проблемное пространство, вы получите кучу производительности. Вы абсолютно уверены, что каждый из этих строк в этой таблице должен быть проверен?
Другая вещь, которую вы можете попробовать, - это DELETE InsertTable FROM InsertTable INNER JOIN ExistingTable ON <Validation criteria>
перед вашей вставкой. Однако ваш пробег может меняться
insert into customers
select *
from newcustomers
where customerid not in (select customerid
from customers)
.. может быть более эффективным. Как говорили другие, убедитесь, что у вас есть индексы для любых полей поиска.
Outer Apply работает на меня...
вместо:
from t1
where not exists (select 1 from t2 where t1.something=t2.something)
Я буду использовать:
from t1
outer apply (
select top 1 1 as found from t2 where t1.something=t2.something
) t2f
where t2f.found is null