Czy dodanie DISTINCT
w poniższym przykładzie ma wpływ na czas wykonywania zapytania?
Czy czasem warto używać go jako podpowiedzi?
SELECT *
FROM A
WHERE A.SomeColumn IN (SELECT DISTINCT B.SomeColumn FROM B)
Czy dodanie DISTINCT
w poniższym przykładzie ma wpływ na czas wykonywania zapytania?
Czy czasem warto używać go jako podpowiedzi?
SELECT *
FROM A
WHERE A.SomeColumn IN (SELECT DISTINCT B.SomeColumn FROM B)
Odpowiedzi:
Zastanawiając się nad takimi rzeczami, powinieneś porównać plany wykonania swoich zapytań.
Kształt planu wykonania zapytania będzie się oczywiście różnić w zależności od liczby wierszy w tabelach i zdefiniowanych indeksów.
Jednym ze scenariuszy, który pokazuje, że nie ma różnicy w wydajności jest sytuacja, gdy jest znacznie więcej wierszy A
niż jest w B
. Optymalizator następnie wybierze B
stół sterujący w zagnieżdżonej pętli sprzężenia z A
. Aby odzyskać poprawny wynik, musi użyć tabeli agregacji strumienia B
w obu zapytaniach, aby uzyskać tylko odrębne wiersze B
. W tym przypadku odrębne słowo kluczowe nie ma wpływu na wydajność.
Plan wykonania dla dwóch innych oczywistych przypadków do przetestowania, więcej wierszy w B niż A i równa liczba wierszy w tabelach, pokazuje również dokładnie ten sam plan wykonania dla zapytań.
Aktualizacja
Przed optymalizacją zapytania zapytanie przechodzi przez fazę uproszczenia. Możesz zobaczyć, jak wygląda drzewo logiczne, używając flagi śledzenia 8606.
Drzewo wprowadzania zapytań jest wyraźnie różne, ale po uproszczeniu są takie same.
Zobacz: Więcej nieudokumentowanych flag śledzenia i flagi śledzenia głębokiego nurkowania - część 2
Drzewo wejściowe i drzewo uproszczone dla zapytania przy użyciu odrębnych:
*** 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
*******************
Drzewo wejściowe i drzewo uproszczone dla zapytania nie używającego odrębnego:
*** 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
*******************