クエリ分析の基礎
GreenplumはPostgreSQLを基盤として開発されたため、実行計画の多くはPostgreSQLと共通しています。しかし、Greenplumは分散並列データベースであるため、SQL実行において多くのMPP(Massively Parallel Processing)の特徴が見られます。そのため、Greenplumの実行計画を理解する際には、その分散アーキテクチャを深く理解することが重要です。適切な実行計画の調整により、SQLのパフォーマンスを大幅に向上させることができます。
パフォーマンスの問題があるクエリの計画を確認することで、最適化の機会を見つけることができます。
Greenplumデータベースは各クエリに対して最適なクエリ計画を設計します。クエリ計画がクエリとデータ構造に適していることは、良好なパフォーマンスを得るために不可欠です。クエリ計画は、Greenplumデータベースが並列実行環境でクエリをどのように実行するかを定義します。クエリオプティマイザは、データベースが保持する統計情報を利用して、最も低いコストを持つクエリ計画を選択します。
コストはディスクI/Oを基準として測定され、取得するディスクページ数で表されます。目標は計画の総実行コストを最小化することです。
-- 実行計画の確認
EXPLAIN SELECT * FROM names WHERE id=22;
-- 実際の実行時間も表示
EXPLAIN ANALYZE SELECT * FROM names WHERE id=22;
注意:Greenplumデータベースでは、デフォルトのGPORCAオプティマイザと従来のクエリオプティマイザが共存しています。GPORCAが生成するEXPLAIN出力は、従来のクエリオプティマイザとは異なります。
デフォルトでは、Greenplumデータベースは可能な限りGPORCAを使用して実行計画を生成します。
実行計画入門
実行計画とは
実行計画とは、データベースがSQLを実行する際の手順であり、アルゴリズムのようなものです。Greenplumの実行計画を読み解くことは、SQLの正確性とパフォーマンスを理解するために非常に役立ちます。実行計画は、データベース利用者がデータベース内部構造を理解する重要な手段です。
実行計画の確認方法
PostgreSQLと同様に、GreenplumではEXPLAINコマンドを使用して実行計画を確認できます。基本的な構文は以下の通りです:
EXPLAIN [ ANALYZE ] [ VERBOSE ] statement
- ANALYZE: コマンドを実際に実行し、実際の実行時間を表示します。
- VERBOSE: 計画ツリーの完全な内部表現を表示します。通常はデバッグ目的でのみ使用されます。
- statement: SQL文(SELECT、INSERT、UPDATE、DELETE、VALUES、EXECUTE、DECLAREなど)
分散実行計画概要
ShareNothingアーキテクチャの特徴:
- 下層のデータは完全に分散されています。
- 各セグメントにはデータの一部のみが格納されます。
- すべてのノードはネットワークを通じて接続されています。
再分配とブロードキャスト
異なるノード上の関連データは、通常のリレーショナルデータベースでは結合できません。関連するデータはネットワーク経由で計算ノードに移動する必要があり、これにはデータ移動が伴います。データ移動にはブロードキャストと再分配の2種類があります。
再分配では、結合キーと分布キーが一致しないテーブルの場合、SLICE1でテーブルの再分配が必要になります。これは各ノード間でのデータ交換と考えることができます。
ブロードキャストと再分配には重要な概念「スライス(Slice)」があります。各ブロードキャストや再分配はスライスを生成し、各データノードではそのスライスを処理するプロセスが起動されます。
Greenplumマスターの役割
- 実行計画の解析と配信
- 子ノードからのデータ収集
- 全セグメントのソート済みデータのマージ操作
- 集約関数の最終計算
- 一意のシーケンス機能(パーティション指定なしのウィンドウ関数など)
実行計画の用語
(1) Seq Scan: シーケンシャルスキャン
データファイルを先頭から末尾まで読み込む最も基本的な方式です。ディスクの読み書き特性に合っており、アナリティクス系のクエリに適しています。
(2) Index Scan: インデックススキャン
インデックスを使用してデータを特定します。フィルタ後のデータ量が少ない場合に効果的です。
(3) Bitmap Heap Scan: ビットマップヒープスキャン
インデックスで特定したデータが全体の大きな割合を占める場合に使用されます。
(4) Tid Scan: CTIDによるスキャン
-- CTIDを使用したクエリ
SELECT * FROM test1 WHERE ctid='(1,1)' AND gp_segment_id=1;
(5) Subquery Scan: サブクエリスキャン
サブクエリの結果に対するシーケンシャルスキャンを行います。
(6) Function Scan: 関数スキャン
EXPLAIN SELECT * FROM generate_series(1,10);
分散実行のモーション操作
(1) Gather Motion(N:1): 集約操作
マスターで全子ノードのデータを集約します。
(2) Broadcast Motion(N:N): ブロードキャスト
各セグメントのテーブルデータを全セグメントに送信します。
(3) Redistribute Motion(N:N): 再分配
新しい分布キーに基づいてデータを再配置します。
(4) スライス(Slice)
Broadcast Motion 6:6 (slice1)
Gather Motion 6:1 (slice1)
集約方式の比較
- HashAggregate: GROUP BYフィールドのハッシュ値を計算してメモリ内でリストを維持
- GroupAggregate: データをソートしてグループ単位でスキャン
結合方式
GreenplumではHash Join、NestLoop、Merge Joinの3つの結合方式をサポートしています。以下にサンプルテーブルを作成します:
CREATE TABLE test1 (id int, values varchar(256)) DISTRIBUTED BY (id);
CREATE TABLE test2 (id int, values varchar(256)) DISTRIBUTED BY (id);