回答:
このようなことについて疑問に思うときは、クエリの実行計画を比較する必要があります。
もちろん、クエリの実行プランの形状は、テーブル内の行数と定義されているインデックスによって異なります。
パフォーマンスに違いがないことを示す1つのシナリオは、にあるよりもかなり多くの行があるA
場合B
です。オプティマイザはB
、ネストされたループ結合の駆動テーブルとしてを選択しますA
。正しい結果を取得するにはB
、両方のクエリでテーブルのStream Aggregateを使用して、から個別の行のみを取得する必要がありますB
。したがって、この場合、distinctキーワードはパフォーマンスに影響を与えません。
テストする他の2つの明白なケース、AよりもBの行が多く、テーブルの行数が等しい場合の実行計画も、クエリに対してまったく同じ実行計画を示しています。
更新
クエリの最適化が行われる前に、クエリは単純化フェーズを通過します。トレースフラグ8606を使用して、論理ツリーがどのように見えるかを確認できます。
クエリの入力ツリーは明らかに異なりますが、単純化した後は同じです。
参照:文書化されていないクエリオプティマイザートレースフラグとクエリオプティマイザーの詳細-パート2
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
*******************
個別を使用しないクエリの入力ツリーと簡易ツリー:
*** 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
*******************