Ist die Verwendung von DISTINCT als Hinweis in Unterabfragen nützlich?

18

Hat das Hinzufügen DISTINCTim folgenden Beispiel Auswirkungen auf die Abfragelaufzeit?
Ist es ratsam, es manchmal als Hinweis zu verwenden?

SELECT *
FROM   A
WHERE  A.SomeColumn IN (SELECT DISTINCT B.SomeColumn FROM B) 
Yosi Dahari
quelle

Antworten:

25

Wenn Sie sich über solche Dinge wundern, sollten Sie die Ausführungspläne für Ihre Abfragen vergleichen.

Die Form des Ausführungsplans für Ihre Abfrage hängt natürlich davon ab, wie viele Zeilen Ihre Tabellen enthalten und welche Indizes definiert sind.
Ein Szenario, das zeigt, dass es keinen Leistungsunterschied gibt, besteht darin, dass wesentlich mehr Zeilen Aals Zeilen enthalten sind B. Das Optimierungsprogramm wählt dann Beine Verknüpfung in einer verschachtelten Schleife als Driving-Tabelle aus A. Um ein korrektes Ergebnis zu erhalten, muss Bin beiden Abfragen ein Stream-Aggregat für die Tabelle verwendet werden, von dem nur die einzelnen Zeilen abgerufen werden B. In diesem Fall hat das eindeutige Schlüsselwort also keinen Einfluss auf die Leistung.

Bildbeschreibung hier eingeben

Bildbeschreibung hier eingeben

Der Ausführungsplan für zwei andere offensichtliche zu testende Fälle, mehr Zeilen in B als A und die gleiche Anzahl von Zeilen in den Tabellen, zeigt auch den exakt gleichen Ausführungsplan für die Abfragen.

Aktualisieren

Vor der Abfrageoptimierung durchläuft die Abfrage eine Vereinfachungsphase. Mit dem Trace-Flag 8606 können Sie sehen, wie der logische Baum aussieht.

Der Eingabebaum für die Abfragen ist deutlich unterschiedlich, aber nach der Vereinfachung sind sie gleich.

Ref: Weitere undokumentierte Ablaufverfolgungsflags für das Abfrageoptimierungsprogramm und Deep Dive für das Abfrageoptimierungsprogramm - Teil 2

Eingabebaum und vereinfachter Baum für die Abfrage mit distinct:

*** 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
*******************

Eingabebaum und vereinfachter Baum für die Abfrage, die nicht distinct verwenden:

*** 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
*******************
Mikael Eriksson
quelle