手順1: 実行計画確認
EXPLAIN
SELECT ... -- 重いクエリをそのまま
;
手順2: テーブルのDISTKEY/SORTKEY確認
SELECT tablename, diststyle, distkey, sortkey1
FROM pg_table_def
WHERE tablename IN ('テーブルA', 'テーブルB');
手順3: テーブルの統計情報確認
SELECT tablename, stats_off
FROM svv_table_info
WHERE tablename IN ('テーブルA', 'テーブルB');
stats_off が高いほど統計情報が古い(100が最悪)
結果別の対策
| EXPLAINの結果 | 原因 | 対策 |
|---|---|---|
DS_BCAST_INNER が出る | JOINカラムにDISTKEYなし | JOINカラムにDISTKEY設定(テーブル再作成必要) |
DS_BCAST_INNER が出ない | DISTKEY設定済み | 次を確認 |
stats_off が高い | 統計情報が古い | ANALYZE テーブル名; |
| 統計情報は正常 | データ量の問題 | クエリ自体の見直し、不要カラムを減らす |
まずEXPLAINの結果を見て DS_BCAST_INNER があるかないかで方針が変わります。
DS_BCAST_INNER が出ない DISTKEY設定済み 次を確認これなに
書き漏らしました。DS_BCAST_INNERが出ない場合の次の確認は:
EXPLAIN内のコスト数値を見る
XN Hash Join (cost=xxxxxx..xxxxxx rows=xxx width=xx)
このcostの数値が異常に大きい場合は統計情報が古くてRedshiftが誤った実行計画を立てている可能性があります。
その場合は:
ANALYZE テーブルA;
ANALYZE テーブルB;
で統計情報を更新してから再度EXPLAINを実行して数値が変わるか確認してください。
XN Hash Join (cost=xxxxxx..xxxxxx rows=xxx width=xx)ああこんなんあったきがするわ
それが出ているならJOINの処理自体は動いています。
次にその cost= の数値がどのくらいか確認してみてください。数値が大きければ大きいほど重い処理になっています。
あとその上に DS_BCAST_INNER や DS_DIST_ALL の記載がないか合わせて確認してみてください。
