L'uso di DISTINCT come suggerimento nelle sottoquery è utile?


18

L'aggiunta DISTINCTnell'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:


25

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 Aquante ce ne siano B. L'ottimizzatore sceglierà quindi Bcome tabella guida in un join loop annidato A. Per ottenere un risultato corretto, è necessario utilizzare un aggregato di flusso sulla tabella Bin entrambe le query per ottenere solo le righe distinte B. Pertanto, in questo caso la parola chiave distinta non ha alcun impatto sulle prestazioni.

inserisci qui la descrizione dell'immagine

inserisci qui la descrizione dell'immagine

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
*******************
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.