L'aggiunta DISTINCT
nell'esempio seguente ha alcun impatto sul tempo di esecuzione della query?
È saggio usarlo come suggerimento a volte?
SELECT *
FROM A
WHERE A.SomeColumn IN (SELECT DISTINCT B.SomeColumn FROM B)
L'aggiunta DISTINCT
nell'esempio seguente ha alcun impatto sul tempo di esecuzione della query?
È saggio usarlo come suggerimento a volte?
SELECT *
FROM A
WHERE A.SomeColumn IN (SELECT DISTINCT B.SomeColumn FROM B)
Risposte:
Quando ti chiedi cose del genere, dovresti confrontare i piani di esecuzione delle tue domande.
La forma del piano di esecuzione per la tua query varierà ovviamente a seconda di quante righe hai nelle tue tabelle e quali indici sono definiti.
Uno scenario che mostra che non vi è alcuna differenza nelle prestazioni è quando vi sono sostanzialmente più righe di A
quante ce ne siano B
. L'ottimizzatore sceglierà quindi B
come tabella guida in un join loop annidato A
. Per ottenere un risultato corretto, è necessario utilizzare un aggregato di flusso sulla tabella B
in entrambe le query per ottenere solo le righe distinte B
. Pertanto, in questo caso la parola chiave distinta non ha alcun impatto sulle prestazioni.
Il piano di esecuzione per altri due casi evidenti da testare, più righe in B di A e uguale numero di righe nelle tabelle, mostra anche lo stesso piano di esecuzione esatto per le query.
Aggiornare
Prima dell'ottimizzazione della query, la query passa attraverso una fase di semplificazione. Puoi vedere come appare l'albero logico usando il flag di traccia 8606.
L'albero di input per le query è chiaramente diverso ma dopo la semplificazione sono gli stessi.
Rif: Altre informazioni non documentate Query Optimizer Traccia Flag e Query Optimizer Deep Dive - Parte 2
Albero di input e albero semplificato per la query utilizzando distinti:
*** Input Tree: ***
LogOp_Project QCOL: [xx].[dbo].[A].SomeColumn
LogOp_Select
LogOp_Get TBL: A A TableID=213679909 TableReferenceID=0 IsRow: COL: IsBaseRow1002
ScaOp_SomeComp 2
ScaOp_Identifier QCOL: [xx].[dbo].[A].SomeColumn
LogOp_GbAgg OUT(QCOL: [xx].[dbo].[B].SomeColumn,) BY(QCOL: [xx].[dbo].[B].SomeColumn,)
LogOp_Project
LogOp_Project
LogOp_Get TBL: B B TableID=229679966 TableReferenceID=0 IsRow: COL: IsBaseRow1006
AncOp_PrjList
AncOp_PrjList
AncOp_PrjList
AncOp_PrjList
*******************
*** Simplified Tree: ***
LogOp_LeftSemiJoin
LogOp_Get TBL: A A TableID=213679909 TableReferenceID=0 IsRow: COL: IsBaseRow1002
LogOp_Get TBL: B B TableID=229679966 TableReferenceID=0 IsRow: COL: IsBaseRow1006
ScaOp_Comp x_cmpEq
ScaOp_Identifier QCOL: [xx].[dbo].[A].SomeColumn
ScaOp_Identifier QCOL: [xx].[dbo].[B].SomeColumn
*******************
Albero di input e albero semplificato per query che non utilizzano distinti:
*** Input Tree: ***
LogOp_Project QCOL: [xx].[dbo].[A].SomeColumn
LogOp_Select
LogOp_Get TBL: A A TableID=213679909 TableReferenceID=0 IsRow: COL: IsBaseRow1002
ScaOp_SomeComp 2
ScaOp_Identifier QCOL: [xx].[dbo].[A].SomeColumn
LogOp_Project
LogOp_Get TBL: B B TableID=229679966 TableReferenceID=0 IsRow: COL: IsBaseRow1006
AncOp_PrjList
AncOp_PrjList
*******************
*** Simplified Tree: ***
LogOp_LeftSemiJoin
LogOp_Get TBL: A A TableID=213679909 TableReferenceID=0 IsRow: COL: IsBaseRow1002
LogOp_Get TBL: B B TableID=229679966 TableReferenceID=0 IsRow: COL: IsBaseRow1006
ScaOp_Comp x_cmpEq
ScaOp_Identifier QCOL: [xx].[dbo].[A].SomeColumn
ScaOp_Identifier QCOL: [xx].[dbo].[B].SomeColumn
*******************