SQL - verbessern NICHT VORHANDEN Abfrageleistung
-
23-08-2019 - |
Frage
Gibt es eine Möglichkeit ich diese Art von SQL-Abfrageleistung verbessern kann:
INSERT
INTO ...
WHERE NOT EXISTS(Validation...)
Das Problem ist, wenn ich viele Daten in meinem Tisch (wie Millionen von Zeilen) habe, die Ausführung der WHERE NOT EXISTS
Klausel, wenn sehr langsam. Ich habe diese Überprüfung zu tun, weil ich nicht duplizierten Daten einfügen kann.
Ich verwende SQL Server 2005
thx
Lösung
Achten Sie darauf, auf indizierte Spalten suchen, ohne Manipulation der Daten in diesen Spalten (wie etc String).
Andere Tipps
Aus der Spitze von meinem Kopf, könnte man so etwas versuchen:
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
Versuchen Sie NICHT VORHANDEN ersetzen mit einem linken äußeren Verknüpfung, führt es manchmal besser in großen Datensatz.
Achten Sie auf die andere Antwort in Bezug auf die Indizierung. NICHT VORHANDEN ist in der Regel recht schnell, wenn Sie gute Indizes haben.
Aber ich Haben hatte Probleme mit der Leistung Aussagen wie Sie beschreiben. Eine Methode, die ich verwendet habe, um das zu bekommen, ist eine temporäre Tabelle für die Kandidatenwerte zu verwenden, führen Sie eine DELETE FROM ... WHERE EXISTS (...), und dann blind den Rest INSERT. Innerhalb einer Transaktion, natürlich, Rennbedingungen zu vermeiden. Splitting die Abfragen manchmal bis ermöglicht es den Optimierer seine Arbeit zu tun, ohne verwirrt zu werden.
Wenn Sie alle Ihre Problemraum reduzieren, dann werden Sie jede Menge Leistung gewinnen. Sind Sie absolut sicher, dass jedes einzelne dieser Zeilen in dieser Tabelle überprüft werden muss?
Das andere, was Sie vielleicht versuchen, ist ein DELETE InsertTable FROM InsertTable INNER JOIN ExistingTable ON <Validation criteria>
vor Ihrem Einsatz. Allerdings können Sie Ihre Laufleistung variieren
insert into customers
select *
from newcustomers
where customerid not in (select customerid
from customers)
.. kann effizienter sein. Wie schon andere gesagt haben, stellen Sie sicher, dass Sie bekam Indizes auf irgendwelchen Nachschlagefelder haben.