2012-06-29 3 views
1

J'effectue beaucoup d'insertions à partir d'une table de détail dans une table récapitulative dans SQL Server. J'utilise actuellement LEFT OUTER JOIN pour déterminer si la ligne de la table de détail existe déjà dans le tableau récapitulatif avant de l'insérer comme dans l'exemple ci-dessous:Quelle est la manière la plus efficace d'exécuter un INSERT selon qu'il existe déjà?

INSERT INTO TableA 
     (columnA 
     ,columnB 
     ,columnC) 
SELECT 
    b.columnA, 
    b.columnB, 
    b.columnC 
FROM TableB b 
    LEFT OUTER JOIN TableA a 
     on a.columnA = b.columnA 
WHERE 
    a.columnA IS NULL 

J'ai trouvé que cette méthode prend une quantité considérable de même s'il n'y a pas de lignes à insérer car il doit comparer toutes les lignes pour déterminer ce qui existe déjà. Dans ce scénario, je considérerais normalement ajouter un drapeau à TableB pour dire quelles lignes ont été insérées.

Cependant, il existe plusieurs scénarios différents pour une ligne TableB à insérer dans TableA qui nécessiterait plusieurs drapeaux et je préférerais ne pas utiliser l'espace de stockage TableB est très grand et se agrandissant.

Merci pour tout conseil.

+0

Avez-vous essayé d'utiliser les instructions de fusion à la place? Je pense que sql-server fait une optimisation supplémentaire en l'utilisant à la place. – mfussenegger

+1

Pouvez-vous également afficher les PK et les index sur ces tables? –

Répondre

3
INSERT INTO TableA (columnA, columnB, columnC) 
SELECT 
    b.columnA, 
    b.columnB, 
    b.columnC 
FROM TableB as b 
where not exists (select 1 from TableA as xx where xx.columnA = b.columnA) ; 
+0

Wow, bonne suggestion. J'ai modifié l'un de mes plus petits scripts qui n'a actuellement aucun enregistrement à insérer mais qui prenait auparavant presque 3 minutes à courir et après avoir appliqué votre méthode, cela a pris 1 seconde. Merci! Je suppose que je n'ai pas entièrement compris le mot-clé "existe". – Troy

Questions connexes