2017-04-18 4 views
0

L'exemple de sous-requête corrélée donné dans un livre est le suivant;Différence entre la sous-requête et la sous-requête corrélée pour le code donné

Les clients qui ont commandé le 12 Février 2007

SELECT custid, companyname 
FROM Sales.Customers AS C 
WHERE EXISTS 
    (SELECT * 
    FROM Sales.Orders AS O 
    WHERE O.custid = C.custid 
    AND O.orderdate = '20070212'); 

Mais, j'écrit le code suivant dans le même but en utilisant la sous-requête simple,

SELECT custid, companyname 
FROM Sales.Customers 
WHERE custid IN 
    (SELECT [custid] FROM [Sales].[Orders] 
    WHERE [orderdate] ='20070212') 

deux donne une sortie identique. Quelle méthode est la meilleure? et pourquoi? et je ne comprends pas l'utilisation de EXISTS ici dans le premier ensemble de codes

+1

Vous pouvez lire ici (http://stackoverflow.com/questions/2065329/sql-server-in-vs-exists-performance), en fonction de la version de SQL Server que vous utilisez, les performances peuvent être différentes. Comme vous pouvez le lire dans les réponses et les commentaires, à partir de 2008, l'optimiseur traitera à la fois IN et EXISTS. –

+0

EXISTS évalue le select, si le SELECT renvoie des lignes, alors EXISTS évalue à TRUE, sinon à FALSE. La méthode la plus efficace pourrait être la meilleure;) Pour savoir ce qui est fait différemment, vous devrez étudier le plan d'exécution des requêtes. Il se pourrait bien que vous obteniez le même plan d'exécution, ce qui signifierait que les deux requêtes sont en fait identiques. –

Répondre

1

J'ai essayé requêtes similaires sur mes propres données sur SQL Server 2016 SP !:

select 
* 
from EXT.dbo_CUSTTABLE 
where ACCOUNTNUM in 
(select CUSTACCOUNT from EXT.dbo_SALESLINE b 
    where b.CREATEDDATETIME between '20170101 00:00' and '20170102 23:59'); 

select 
* 
from EXT.dbo_CUSTTABLE a 
where exists 
(select * from EXT.dbo_SALESLINE b 
    where a.ACCOUNTNUM=b.CUSTACCOUNT 
    and b.CREATEDDATETIME between '20170101 00:00' and '20170102 23:59'); 

Regardez les plans d'exécution, ils sont identique!

enter image description here

Si j'ajoute un index ordonné en clusters sur la table des clients, et un index sur la salesline, nous obtenons une requête plus efficace, avec recherche d'index et jointure interne, au lieu de scans de table et les jointures de hachage, mais toujours identique !:

enter image description here

maintenant, si vous utilisez une autre version du serveur SQL youre les résultats peuvent varier, étant donné que les changements de optimiseur de requêtes entre les versions.