SQL - améliorer PAS EXISTE les performances des requêtes
-
23-08-2019 - |
Question
Est-il possible que je peux améliorer ce genre de requête SQL performance:
INSERT
INTO ...
WHERE NOT EXISTS(Validation...)
Le problème est quand j'ai beaucoup de données dans ma table (comme millions de lignes), l'exécution de la clause de WHERE NOT EXISTS
si elle est très lente. Je dois faire cette vérification parce que je ne peux pas insérer des données dupliquées.
J'utilise SQLServer 2005
thx
La solution
Assurez-vous que vous êtes à la recherche sur les colonnes indexées, sans manipulation des données dans ces colonnes (comme etc substring.)
Autres conseils
Du haut de ma tête, vous pouvez essayer quelque chose comme:
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
Essayez de remplacer le NOT EXISTS avec une jointure externe gauche, il effectue parfois mieux dans les grands ensembles de données.
Faites attention à l'autre réponse concernant l'indexation. NOT EXISTS est généralement assez rapide si vous avez de bons indices.
Mais je Vous eu des problèmes de performance avec des déclarations comme vous décrivez. Une méthode que je l'ai utilisé pour se déplacer est d'utiliser une table temporaire pour les valeurs candidates, effectuer une DELETE FROM ... WHERE EXISTS (...), puis INSERT aveuglément le reste. A l'intérieur d'une transaction, bien sûr, pour éviter les conditions de course. Fractionnement les requêtes permet parfois l'optimiseur de faire son travail sans se confondre.
Si vous pouvez réduire à tout votre espace de problème, vous gagnerez des tas de performances. Êtes-vous absolument sûr que chacun de ces lignes dans cette table doit être cochée?
L'autre chose que vous pourriez vouloir essayer est un DELETE InsertTable FROM InsertTable INNER JOIN ExistingTable ON <Validation criteria>
avant votre insert. Cependant, votre kilométrage peut varier
insert into customers
select *
from newcustomers
where customerid not in (select customerid
from customers)
.. peut-être plus efficace. Comme d'autres l'ont dit, assurez-vous que vous avez des index sur les champs de recherche.