1

次のクエリがあります。 DataStagingは1000万行の大きなテーブルです。

Product i小さいテーブルには1000行あります。

product_idを使用してを見つける必要があり、テーブルrefには2つあるため、テーブルを2回結合する必要があります。ref (ref1,ref2) Product

    UPDATE  dbo.DataStaging
    SET     ProductId = COALESCE(Ref1_Pid, Ref2_Pid, 0) 
    FROM    dbo.DataStaging s
            LEFT JOIN ( SELECT  id [Ref1_Pid] ,
                                Ref1
                        FROM    dbo.Product
                        WHERE   isActive = 1
                      ) p1 ON s.[Ref] = p1.Ref1
            LEFT JOIN ( SELECT  id [Ref2_Pid] ,
                                Ref2
                        FROM    dbo.Product
                        WHERE   IsActive = 1
                      ) p2 ON s.[Ref] = p1.Ref2
           
    WHERE   s.TypeId = 1
            AND s.StatusId = 2

これは製品テーブルPK_Productの主キーであり、Non_ClusteredIndexを自由に追加できます。

(1)3つのインデックス:NC_index on(IsActive)、NC_Index on(Ref1)、NC_Index on(Ref2)

(2)2つの複合インデックス:NC_Index on(IsActive、Ref1)、NC_Index on(IsActive、Ref2)

(3)1つの複合インデックス:NC_Index on(IsActive、Ref1、Ref2)

(1)の場合、主キーPK_Productを使用してテーブルをスキャンしますが、NCインデックスはスキャンしません。

(2)の場合、各インデックスでNC_indexスキャンを使用します。

(3)同じインデックスでNC_index Scanを使用しますが、行サイズは(2)の2倍です。

その結果、パフォーマンス(2)>(3)>(1)

私の質問は、

(1)NCインデックスをスキャンしないのはなぜですか?

(2)や(3)のようなインデックスを作成する場合の欠点は何ですか?

上記のクエリがの最も重いプロセスであると想定しますが、条件の異なるステートメントでテーブルを使用する方法Productは何百もあります。上記のクエリのパフォーマンスが(2)>(3)であっても、(2)は(3)よりも優れたアプローチですか?stored procsproductselectwhere

(今のところdataStagingのインデックスは無視してください)

4

1 に答える 1

2

(1) IsActive のインデックスと Ref1/Ref2 のインデックスの結合が必要になりますが、これはあまり最適ではないと見なされます。

私は(2)のバリエーションに行きます-インクルードを持つ2つのフィルタリングされたインデックス:

create index IX_Product_Ref1 on Product (Ref1) include(id) where (IsActive = 1)
create index IX_Product_Ref2 on Product (Ref2) include(id) where (IsActive = 1)

(3) IsActive、Ref1、および Ref2 を一緒にクエリする場合にのみ良い考えです。

また、このようにクエリを書くことはできませんか?

UPDATE  dbo.DataStaging
    SET     ProductId = isnull(p.id, p2.id) 
FROM    dbo.DataStaging s
LEFT JOIN dbo.Product p ON s.[Ref] = p.Ref1 and p.IsActive = 1
LEFT JOIN dbo.Product p2 ON s.[Ref] = p2.Ref2 and p2.IsActive = 1
WHERE s.TypeId = 1
AND s.StatusId = 2
于 2013-02-27T18:28:56.203 に答える