web-dev-qa-db-ja.com

EXCEPTとINTERSECT:論理計画におけるパッシブプロジェクションの目的

次のEXCEPTクエリは、一見無意味な投影の論理プランを作成します。これはINTERSECTでも発生します。

予測の目的は何ですか?例えば外部投影が何かを指定する別のEXCEPTクエリはありますか?

クエリ:

use AdventureWorks2017

select p.ProductId
from Production.Product as p
except
select pinv.ProductID
from Production.ProductInventory as pinv
option (recompile, querytraceon 8605, querytraceon 3604)

変換されたツリー:

    LogOp_Select

        LogOp_GbAgg OUT(QCOL: [p].ProductID,) BY(QCOL: [p].ProductID,)

            LogOp_Project -- << ?? PASSIVE PROJECTION ??

                LogOp_Project

                    LogOp_Get TBL: Production.Product(alias TBL: p) Production.Product TableID=482100758 TableReferenceID=0 IsRow: COL: IsBaseRow1000 

                    AncOp_PrjList 

                AncOp_PrjList 

            AncOp_PrjList 

        ScaOp_Exists 

            LogOp_Select

                LogOp_Project

                    LogOp_Get TBL: Production.ProductInventory(alias TBL: pinv) Production.ProductInventory TableID=914102297 TableReferenceID=0 IsRow: COL: IsBaseRow1001 

                    AncOp_PrjList 

                ScaOp_Comp x_cmpEq

                    ScaOp_Identifier QCOL: [p].ProductID

                    ScaOp_Identifier QCOL: [pinv].ProductID
8
Paul Holmes

クエリオプティマイザーの内部では、外部で説明できる理由が実際にはないさまざまな処理があります。オプティマイザに表示されるプロジェクトは、最終的にはオプティマイザの最後に書き直され、式を「平坦化」します。したがって、オプティマイザには、コードの実装方法の一部である検索結果があり、実際には何も機能せず、オプティマイザの一部で1つのサブツリーが作成された場所に、プロジェクトを統合することができます。しかし、当初は意図されていなかった場所で後で使用されます。これを引き起こす可能性のある物理的な実装の詳細がいくつかあります。それらのどれも計画品質の点でユーザーにとって重要ではありません(ほとんどすべての場合-検索でこれらを重要ではないようにする作業を行いました)。

だから、私はただ手を振って、「彼の身元を確認する必要はありません。彼は彼の仕事に取り掛かることができます。一緒に進んでください」と言います。

14

これに対する完全な満足のいく答えはありませんが、DISTINCTはプロジェクトとgroup-by集約に変換されます。

EXCEPTINTERSECT はどちらも、最初のテーブル式に暗黙のDISTINCTが付いています。このDISTINCTがツリーの「空の」プロジェクトになります。無害です。

DISTINCTを同等のGROUP BYとして記述した場合、空のプロジェクトは表示されません。集計の後にプロジェクトが表示されます。

SELECT DISTINCT P.ProductID
FROM Production.Product AS P
OPTION (QUERYTRACEON 3604, QUERYTRACEON 8605);
LogOp_GbAgg OUT(QCOL: [P].ProductID,) BY(QCOL: [P].ProductID,)
    LogOp_Project
        LogOp_Project QCOL: [P].ProductID
            LogOp_Get TBL: Production.Product(alias TBL: P)
            AncOp_PrjList 
        AncOp_PrjList 
    AncOp_PrjList
SELECT P.ProductID
FROM Production.Product AS P
GROUP BY p.ProductID
OPTION (QUERYTRACEON 3604, QUERYTRACEON 8605);
LogOp_Project QCOL: [P].ProductID
    LogOp_GbAgg OUT(QCOL: [P].ProductID,) BY(QCOL: [P].ProductID,)
        LogOp_Project
            LogOp_Get TBL: Production.Product(alias TBL: P)
            AncOp_PrjList 
        AncOp_PrjList 
    AncOp_PrjList
11
Paul White 9