web-dev-qa-db-ja.com

演算子のハッシュ一致内部結合を削除することによるクエリパフォーマンスの向上

以下のこの質問の内容を自分の状況に適用しようとしていますが、可能であれば、演算子Hash Match(Inner Join)をどのようにして取り除くことができるのか、少し混乱しています。

SQL Serverクエリパフォーマンス-ハッシュマッチ(内部結合)の必要性を排除

私は10%の費用に気づき、それを減らすことができるかどうか疑問に思っていました。以下のクエリプランを参照してください。

enter image description here

この作業は、今日調整しなければならなかったクエリのサドから来ています。

SELECT c.AccountCode, MIN(d.CustomerSID) 
FROM   Stage.Customer c 
INNER JOIN Dimensions.Customer d  ON c.Email = d.Email
                                  OR (
                                          c.HomePostCode = d.HomePostCode
                                       AND c.StrSurname = d.strSurname
                                                                    )
GROUP BY c.AccountCode

これらのインデックスを追加した後:

---------------------------------------------------------------------
-- Create the indexes
---------------------------------------------------------------------

CREATE NONCLUSTERED INDEX IDX_Stage_Customer_HOME_SURNAME_INCL
ON Stage.Customer(HomePostCode ,strSurname)
INCLUDE (AccountCode)
--WHERE HASEMAIL = 0
--WITH (ONLINE=ON, DROP_EXISTING = ON)
go


CREATE NONCLUSTERED INDEX IDX_Dimensions_Customer_HOME_SURNAME_INCL
ON Dimensions.Customer(HomePostCode ,strSurname)
INCLUDE (AccountCode,CustomerSID)
--WHERE HASEMAIL = 0
--WITH (ONLINE=ON, DROP_EXISTING = ON)
go



CREATE NONCLUSTERED INDEX IDX_Stage_Customer_EMAIL_INCL
ON Stage.Customer(EMAIL)
INCLUDE (AccountCode)
--WHERE HASEMAIL = 1
--WITH (ONLINE=ON, DROP_EXISTING = ON)
go


CREATE NONCLUSTERED INDEX IDX_Dimensions_Customer_EMAIL_INCL
ON Dimensions.Customer(EMAIL)
INCLUDE (AccountCode,CustomerSID)
--WHERE HASEMAIL = 1
--WITH (ONLINE=ON, DROP_EXISTING = ON)
go

これは新しいクエリです:

----------------------------------------------------------------------------
-- new query 
----------------------------------------------------------------------------

SELECT * 
FROM (    
SELECT AccountCode
     ,RO=ROW_NUMBER () OVER (PARTITION BY AccountCode ORDER BY CustomerSID)
     --,CustomerSID=MIN(CustomerSID) OVER (PARTITION BY AccountCode ORDER BY AccountCode)
       ,CustomerSID
FROM (    
          SELECT c.AccountCode, D.CustomerSID
       FROM   Stage.Customer c 
       INNER JOIN Dimensions.Customer d  ON c.Email = d.Email

          UNION ALL

          SELECT c.AccountCode, D.CustomerSID
       FROM   Stage.Customer c 
       INNER JOIN Dimensions.Customer d  ON c.HomePostCode = d.HomePostCode
                                        AND c.StrSurname = d.strSurname
) RADHE
) R1
WHERE RO = 1

これにより、クエリの実行時間が8分から1秒に短縮されました。

誰もが幸せですが、それでももっともっとできるかどうか知りたいです。どういうわけかハッシュ一致演算子を削除します。

なぜ最初にそこにあるのですか、すべてのフィールドを照合していますが、なぜハッシュなのですか?

9

以下のリンクは、実行計画に関する知識の良い情報源を提供します。

From 実行プランの基本—ハッシュマッチの混乱 見つかりました:

http://sqlinthewild.co.za/index.php/2007/12/30/execution-plan-operations-joins/ から

「ハッシュ結合は、結合を行うためにハッシュテーブルを作成する必要があるため、より高価な結合演算の1つです。それは、大規模なソートされていない入力に最適な結合です。結合の

ハッシュ結合は、最初に入力の1つを読み取り、結合列をハッシュし、結果のハッシュと列の値をメモリに構築されたハッシュテーブルに入れます。次に、2番目の入力のすべての行を読み取り、それらをハッシュし、結合された行の結果のハッシュバケット内の行をチェックします。」

この投稿へのリンク:

http://blogs.msdn.com/b/craigfr/archive/2006/08/10/687630.aspx

この実行プランを説明できますか? は、ハッシュ一致に固有ではなく関連して、実行プランに関する優れた洞察を提供します。

定数スキャンは、SQL Serverがバケットを作成する方法であり、実行プランの後半にバケットを配置します。私は ここでそれのより完全な説明 を投稿しました。常時スキャンの目的を理解するには、計画をさらに詳しく調べる必要があります。この場合、定数スキャンによって作成されたスペースを埋めるために使用されているのは、Compute Scalarオペレーターです。

Compute Scalarオペレーターは、NULLと値1045876で読み込まれているため、データをフィルター処理する目的でループ結合で使用されることは明らかです。

本当にクールな部分は、この計画が取るに足らないことです。それは最小限の最適化プロセスを経たことを意味します。すべての操作は、マージ間隔につながります。これは、インデックスシークのための最小限の比較演算子のセットを作成するために使用されます( 詳細はこちら )。

この質問では: SSMSで実行プランペインに実際のクエリコストを表示できますか? SQL Serverのマルチステートメントストアドプロシージャのパフォーマンスの問題を修正しています。時間をかけるべき部分を知りたい。

私は クエリコストを読み取るにはどうすればよいですか、それは常にパーセンテージですか? SSMSが実際の実行プランを含めるように指示されている場合でも、「クエリコスト(バッチに対する)」の数値は依然としてコスト見積もりに基づく。これは実際とはかけ離れている場合がある

クエリパフォーマンスの測定:「実行プランクエリコスト」と「所要時間」 2つの異なるクエリのパフォーマンスを比較する必要がある場合に役立つ情報を提供します。

SQL Server実行プランの読み取り には、実行プランを読み取るための優れたヒントがあります。

この主題に関連しているので私が本当に気に入った他の質問/回答、および私の個人的な参照のために引用したいと思います:

実行プランを使用してT-SQLクエリを最適化する方法

sqlはこの手順の適切な計画を生成できますか?

同じSQLステートメントでは実行プランが異なります

14