サブクエリのヒントとしてDISTINCTを使用すると便利ですか?


18

DISTINCT次の例に追加すると、クエリの実行時間に影響がありますか?
時々ヒントとして使用するのが賢明ですか?

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

回答:


25

このようなことについて疑問に思うときは、クエリの実行計画を比較する必要があります。

もちろん、クエリの実行プランの形状は、テーブル内の行数と定義されているインデックスによって異なります。
パフォーマンスに違いがないことを示す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
*******************
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.