Site Meter Inner Join Condition vs. Where Condition - The SQL Server Side of Me

The SQL Server Side of Me

Libero sfogo alle mie curiosità su SQL Server

Inner Join Condition vs. Where Condition

Dopo le prime esperienze con T-SQL, non appena si è un po’ più pratici nello scrivere le query, il pensiero corre subito alle performance: “Bene, ho scritto questa query: funziona. Ma… avrei potuto scriverla meglio, in modo tale da ottenere il risultato nel minor tempo possibile?”

Mi è spesso capitato di pormi la suddetta domanda quando utilizzavo dei join. La domanda si perfezionava in: “Ma se usassi la condizione che sta nella WHERE direttamente nella JOIN condition, potrei avere dei benefici?”. In effetti, la prima cosa che ci viene in mente osservando una query del tipo:

SELECT *
FROM MyTable AS T
    INNER JOIN OtherTable AS OT
    ON T.id = OT.id
WHERE OT.col1 = 'filter'

è quella di immaginare che l’engine prima “unisca” le due tabelle in base alla join condition, e poi ne filtri le righe tramite la where. In realtà l’operazione “unire le due tabelle in base alla join condition” corrisponde a due operazioni logiche:

  1. prodotto cartesiano delle due tabelle
  2. filtro delle righe in base al predicato ON

Dunque il filtro della where elaborerà le righe date come risultato dalla inner join (le righe saranno al più le stesse di MyTable). Qualora si includesse tale filtro nel predicato ON, si avranno differenze nei piani di esecuzione e nelle attività di I/O?

Prendendo come database di esempio AdventureWorks, consideriamo le seguenti due query:

USE AdventureWorks;

SET STATISTICS IO ON; 
 
SELECT *
FROM
    Sales.SalesOrderHeader AS SOH
    INNER JOIN Sales.SalesOrderDetail AS SOD
        ON SOH.SalesOrderID = SOD.SalesOrderID
WHERE
    SOD.ProductID = 756;
 
 
 
SELECT *
FROM
    Sales.SalesOrderHeader AS SOH
    INNER JOIN Sales.SalesOrderDetail AS SOD
        ON SOH.SalesOrderID = SOD.SalesOrderID
           AND SOD.ProductID = 756;

Le statistiche e i piani di esecuzione sono i seguenti:

InnerJoinWhere_IO

image

Dunque la risposta è NO, non ci sono differenze. L’engine valuta allo stesso modo il filtro del predicato ON e il filtro WHERE per l’INNER JOIN in tutti e due i casi.