今回は複数のテーブルを結合するSQLのチューニングを行います。前回と同様にTPC-Hの環境を使います。今回の対象のSQLは以下の通りです。

select
    l_orderkey,
    sum(l_extendedprice * (1 - l_discount)) as revenue,
    o_orderdate,
    o_shippriority

from
    customer,
    orders,
    lineitem
where
    c_mktsegment = 'BUILDING'
    and c_custkey = o_custkey
    and l_orderkey = ovorderkey
    and o_orderdate < '1995-03-15'
    and l_shipdate > '1995-03-15'
group by
    l_orderkey,
    o_orderdate,
    o_shippriority
order by
    revenue desc,
    o_orderdate;

上記のように、今回は「customer」「orders」「lineitem」の3つのテーブルを結合します。各テーブルのリレーションはTPC-Hのサイトを参考にしてください。

The TPC-H Schema 出展:TPC BENCHMARKTM H (Decision Support) Standard Specification Revision 2.17.2

また現時点では、すべてのテーブルはクラスター化カラムストアインデックスで構成されており、ROUND ROBIN分散でディストリビューションされています。

統計情報の取得

統計情報とは、SQL Data Warehouseが実行計画を生成する際のもととなるデータです。統計情報をもとに、SQL Data Warehouseは最適な実行計画を作ります。しかし、SQL Data Warehouseでは統計情報を自動で取得するような機能はありません。今回のデータもSQL Data Warehouseにデータを入れただけで、統計情報の取得は行っていません。まずは、統計情報を取得してみて、実行速度の変化を確認してみましょう。

統計情報の取得は、以下のようにいくつかの種類があります。

  • 単一の列に対する統計情報の取得
  • 複数列に対する統計情報の取得
  • データの中の一部の行のみに対する統計情報の取得

また、MicrosoftのSQL Data Warehouseに関する公式ドキュメントでは、データベース内のすべての列の統計が取得できるストアドプロシージャも用意されていますが、一般的に統計情報の取得、更新の基準は以下の通りです。

  • JOIN、GROUP BY、ORDER BY、DISTINCTの各句に使用されている列で取得
  • 「日付」などで利用されている列は高頻度で更新が必要(特に新しい日付のデータが追加された時はできるだけ取得するようにする)
  • 「性別」などデータの分布があまり変わらない列は更新頻度を下げる。

今回の例では、WHERE句の中で指定されている列に対して、以下のように統計情報を取得します。

CREATE STATISTICS customer_c_custkey ON customer(c_custkey);
CREATE STATISTICS customer_c_mktsegment ON customer(c_mktsegment);
CREATE STATISTICS order_o_custkey ON order(o_custkey);
CREATE STATISTICS order_o_orderkey ON order(o_orderkey);
CREATE STATISTICS order_o_orderdate ON order(o_orderdate);
CREATE STATISTICS lineitem_l_orderkey ON lineitem(l_orderkey);
CREATE STATISTICS lineitem_l_shipdate ON lineitem(l_shipdate);

統計情報の取得前後での実行結果の差は以下の通りです。

オブジェクトの定義やSQLは何も変更をしておらず、統計情報を取得しただけですが、処理が約30%も高速化されていることがわかります。上記のように、統計情報を取得すること、また統計情報をメンテナンス(更新)することがいかに重要かわかっていただけたかと思います。

HASH分散の利用

次にHASH分散の利用を検討してみましょう。

SQL Data Warehouseでは、60のディストリビューションにデータが分散格納されており、コンピュートノードに均等に各ディストリビューションが割り当てられています。

SQLの実行をする際、GROUP BYによるデータの集計や、テーブル同士の結合を行う際に各コンピュートノードで完結して処理できることが非常に重要になります。なぜなら、各コンピュートノードで完結できない場合は、必要なデータを内部的に転送する処理が発生するからです(これは第5回で説明したDMSという機能です)。

この処理はSQL Data Warehouseの処理の中で非常に負荷が高いので、これを防ぐこと、すなわち可能な限り内部のデータ移動をなくし、各コンピュートノードで処理を完結させることがSQL Data Warehouseのチューニングの重要な要素となります。

テーブルの結合を行うようなSQLを実行する場合、ノード間データ移動(DMS)を抑える方法は、ずばりテーブルを「HASH分散」することです。 今回のSQLのWHARE句を見てみましょう。

where
	c_mktsegment = 'BUILDING'   ⇒絞り込み条件
	and c_custkey = o_custkey   ⇒結合条件
	and l_orderkey = o_orderkey  ⇒結合条件
	and o_orderdate < '1995-03-15' ⇒絞り込み条件
	and l_shipdate > '1995-03-15' ⇒絞り込み条件

絞り込み条件はテーブルから必要なデータを絞り込む(フィルターをかける)条件です。結合条件は1つ以上のテーブル同士を結合するための条件となります。この結合条件で指定されている項目にHASH分散のHASH KEYを指定することで、テーブル結合時のノード間データ移動の発生を抑制できます。ノード間データ移動の発生を抑制できるということは、負荷が削減でき、結果として高速な処理につながります。

以下のようなSQLで、既存のROUND ROBIN分散のテーブルをHASH分散に変更しました。

CREATE TABLE orders_HASH

WITH
(
    DISTRIBUTION = HASH(o_orderkey),
    CLUSTERED COLUMNSTORE INDEX
)
AS SELECT * FROM orders;

RENAME OBJECT orders to orders_ROUND_ROBIN;
RENAME OBJECT orders_HASH to orders;

CREATE TABLE lineitem_HASH
WITH
(
    DISTRIBUTION = HASH(l_orderkey),
    CLUSTERED COLUMNSTORE INDEX
)
AS SELECT * FROM lineitem;

RENAME OBJECT lineitem to lineitemROUNDROBIN;
RENAME OBJECT lineitem_hash to lineitem;

なお、テーブルをHASH分散のクラスター化カラムストアインデックスで再作成した後は、統計情報の取得は忘れないでください。

HASH分散を行う際のHASH KEYは複数の列を指定することはできません。このため、orderテーブルのo_custkey列(customerテーブルとの結合条件で使用)とo_orderkey列(lineitemテーブルとの結合条件で使用)のどちらをHASH KEYに指定するか悩ましいところですが、orderテーブルとlineitemテーブルとの結合のほうが、データ件数が多く、データ容量も大きいので、DMSが発生した際の負荷が大きくなることが予想されます。このことから、今回はordersテーブルの_orderkey列、linitemテーブルのl_orderkey列をHASH KEYに指定しています。

2テーブルをHASH分散させた結果は、すべてROUND ROBIN分散の場合と比較して性能はおよそ65%改善しました。

以上が、複数のテーブルを結合するSQLのチューニングの例となります。SQL Data Warehouseでの統計情報の取得は忘れがちですが、きっちり取得・更新するようにしましょう。また、HASH分散を上手に使ってDMSの発生を抑えることが、SQL Data Warehouseのチューニングではとても重要です。逆にいうと、このポイントを押さえていれば、SQL Data Warehouseの性能問題の多くを解決できるのです。

山口 正寛



1984年生まれ。大阪府出身、東京都在住。データベースエンジニア。SQL Server、Oracle、MySQL、PostgreSQLなどのデータベースで、小規模から大規模な案件まで数多く経験。現在ではクラウドの流れに逆らうことなく、「データベース×クラウド」をキーワードに案件対応、セミナー活動、執筆活動など幅広く活動中。株式会社システムサポート所属。