2017-10-13 1 views
0

Supposons que j'ai le code suivant:est IN (SELECT ...) mauvais pour la performance?

SELECT * 
FROM [myTable] 
WHERE [myColumn] IN (SELECT [otherColumn] FROM [myOtherTable]) 

Est-ce que la sous-requête d'exécuter à nouveau et à nouveau pour chaque ligne?

Si oui, puis-je l'exécuter et stocker ses résultats et les utiliser pour chaque ligne à la place? Par exemple:

SELECT [otherColumn] 
INTO #Results 
FROM [myOtherTable] 

SELECT * 
FROM [myTable] 
WHERE [myColumn] IN (#Results) 
+0

L'optimiseur doit mettre en cache ou créer une table temporaire afin qu'il n'exécute pas la sous-requête à plusieurs reprises. C'est relativement bon à ça. Vous devez également vérifier 'EXISTS' –

+0

Non ce n'est pas mauvais pour la performance, SQL Server peut choisir jointure hash ou fusionner jointure (qui évalue la sous-requête une fois) ou boucles imbriquées qui exécuteront différentes parties de la sous-requête pour chaque ligne externe. –

+0

Vous n'obtiendrez pas de performances optimales jusqu'à ce que vous 1) index 2) ajouter à la clause where. –

Répondre

2

L'optimiseur de requête SQL Server est suffisamment intelligent pour ne pas exécuter la même sous-requête encore et encore. Si quelque chose, la table temporaire est moins optimale en raison des étapes supplémentaires après avoir obtenu les résultats.

Vous pouvez le voir en consultant le plan d'exécution de la requête SQL.

enter image description here

Edit: Après avoir examiné plus loin, il peut aussi être plus d'une fois. Apparemment, l'optimiseur de requêtes peut aussi faire beaucoup de choses intéressantes comme convertir votre IN en JOIN pour augmenter les performances. Il y a beaucoup d'informations à ce sujet ici: Number of times a nested query is executed

Néanmoins, consultez votre plan d'exécution pour voir ce que l'optimiseur de requêtes de votre RDMS a décidé de faire.

1

Avez-vous envisagé d'utiliser une jointure à la place? Je pense que cela pourrait être meilleur en termes de performance. Cependant, cela fonctionne uniquement si vous ne vous attendez pas à ce que les doublons se trouvent dans myOtherTable.