SQL Server 2014 データベース システムで TPC-H (SF 10) を使用しています。クエリのパフォーマンスを向上させるために、2 つの最大のテーブル (Lineitem と Orders) を日付列で分割 (同じディスク) することにしました。これは、これらのクエリの多くが日付範囲を使用するためです。最初は週単位のパーティション方式を使用することにし、その後月単位の方式を使用しました。各テーブルで、クラスター化された列ストア インデックスを使用しました。最初の TPC-H クエリを実行しました。
SELECT L_RETURNFLAG,
L_LINESTATUS,
SUM(L_QUANTITY) AS SUM_QTY,
SUM(L_EXTENDEDPRICE) AS SUM_BASE_PRICE,
SUM(L_EXTENDEDPRICE*(1-L_DISCOUNT)) AS SUM_DISC_PRICE,
SUM(L_EXTENDEDPRICE*(1-L_DISCOUNT)*(1+L_TAX)) AS SUM_CHARGE,
AVG(L_QUANTITY) AS AVG_QTY,
AVG(L_EXTENDEDPRICE) AS AVG_PRICE,
AVG(L_DISCOUNT) AS AVG_DISC,
COUNT_BIG(*) AS COUNT_ORDER
FROM LINEITEM
WHERE L_SHIPDATE <= dateadd(dd, - 94, cast('1998-12-01'as date))
GROUP BY L_RETURNFLAG,
L_LINESTATUS
ORDER BY L_RETURNFLAG,
L_LINESTATUS;
上記のクエリに対して次の結果が得られました。
- 毎週のパーティショニング
- アクセスされたパーティション 348 (1..348) (合計 361 パーティション)
- (最後のパーティションにあるため、862194 行は読み取られませんでした)
- 論理読み取り: 1381
- ロブ論理読み取り: 109005
- ロブ物理読み取り: 1371
- ロブ先読み: 200554
- 実行時間: 2807 ミリ秒
- コンパイルCPU: 43
- コンパイル時間: 43
コンパイルメモリ: 1408
毎月のパーティショニング
- アクセスされたパーティション 80 (1..80) (合計 84 パーティション)
- (最後のパーティションにあるため、881.087 行は読み取られませんでした)
- 論理読み取り: 2902
- ロブ論理読み取り: 617554
- ロブ物理読み取り: 388
- ロブ先読み: 260486
- 実行時間: 2680 ミリ秒
- コンパイルCPU: 12
- コンパイル時間: 12
- コンパイルメモリ: 872
それらの最大の違いは、使用されたバッチの数です。毎週のパーティショニングでは約 333.201 のバッチがインデックス スキャンの実行に使用され、毎月のパーティショニングではわずか 191.275 のバッチが使用されました。
私はこの結果について少し混乱しています。最初の実行 (毎週のパーティション) は、読み取り操作が少ない 2 番目の実行よりも高速になると予想していました。月ごとに分割されたテーブルの LOB 論理読み取りは大幅に増加しますが、実行時間、コンパイル CPU、時間、およびメモリは減少します。したがって、月ごとのパーティショニングの方が効率的だと思います。他のクエリの結果はほとんど同じに見えます:( .ここで何が起こっているのかを理解するのを手伝ってくれますか?
そのため、maxdop 1 を使用してもう一度テストを行いました。結果は次のとおりです。
毎週のパーティショニング
- 論理読み取り: 1381
- ロブ論理読み取り: 108619
- ロブ物理読み取り: 1362
- ロブ先読み読み取り: 200664
毎月のパーティショニング
- 論理読み取り: 739
- ロブ論理読み取り: 94901
- ロブ物理読み取り: 402
- ロブ先読み: 262598
これは実行計画です。両方の実行でまったく同じように見えます。詳細は次のとおりです。
http://i.stack.imgur.com/293oN.png
読み取り操作の数の違いは以前ほど大きくなく、毎週のパーティショニングではより多くの物理読み取りがあります。さらに、毎週のパーティショニングでは、より多くの論理読み取りがあります。それは私が期待したものとは正反対です:/。
実行計画、(毎月のパーティション分割) 最初に CI を作成し、その後クラスター化された列ストア インデックスを作成しました (drop existing = on および maxdop 1 を使用)