web-dev-qa-db-ja.com

SQL Serverピボットと複数結合

SQL Server 2005でより効率的に使用できるもの:PIVOTまたはMULTIPLE JOIN?

たとえば、2つの結合を使用してこのクエリを取得しました。

SELECT p.name, pc1.code as code1, pc2.code as code2
FROM product p
    INNER JOIN product_code pc1
    ON p.product_id=pc1.product_id AND pc1.type=1
    INNER JOIN product_code pc2
    ON p.product_id=pc2.product_id AND pc2.type=2

私はPIVOTを使用して同じことを行うことができます:

SELECT name, [1] as code1, [2] as code2
FROM (
    SELECT p.name, pc.type, pc.code
    FROM product p
        INNER JOIN product_code pc
        ON p.product_id=pc.product_id
    WHERE pc.type IN (1,2)) prods1
PIVOT(
    MAX(code) FOR type IN ([1], [2])) prods2

どちらがより効率的ですか?

30

答えはもちろん「依存する」でしょうが、この目的のテストに基づいています...

想定

  1. 100万製品
  2. productproduct_idにクラスター化インデックスを持っています
  3. (すべてではないにしても)ほとんどの製品には、product_codeテーブルに対応する情報があります。
  4. 両方のクエリのproduct_codeに存在する理想的なインデックス。

PIVOTバージョンには、理想的にはインデックスproduct_code(product_id, type) INCLUDE (code)が必要ですが、JOINバージョンには、理想的にはインデックスproduct_code(type,product_id) INCLUDE (code)が必要です

これらが適切な場合、以下の計画を提示します

Plans

その場合、JOINバージョンの方が効率的です。

type 1type 2がテーブル内の唯一のtypesである場合、PIVOTバージョンは、product_codeを2回シークする必要がないため、読み取りの数の点でわずかにEdgeを持ちますが、追加のオーバーヘッドが上回るストリーム集約演算子

ピボット

Table 'product_code'. Scan count 1, logical reads 10467
Table 'product'. Scan count 1, logical reads 4750
   CPU time = 3297 ms,  elapsed time = 3260 ms.

参加する

Table 'product_code'. Scan count 2, logical reads 10471
Table 'product'. Scan count 1, logical reads 4750
   CPU time = 1906 ms,  elapsed time = 1866 ms.

12以外の追加のtypeレコードがある場合、JOINプランはtype,product_idを使用しているため、PIVOTバージョンはproduct_id, typeインデックスの関連セクションで結合を結合するだけなので、その利点が高まるため、追加のtype行をスキャンする必要があります1および2行と混在しています。

31
Martin Smith

私は誰もあなたのインデックスとテーブルのサイズの知識なしでどちらがより効率的であるかをあなたに言うことができないと思います。

つまり、どちらがより効率的であるかについて仮説を立てるのではなく、これら2つのクエリの実行計画を分析する必要があります。

5
Jesse