使ってみませんか?pg hint_plan

5,031 views
4,706 views

Published on

第25回しくみ+アプリケーション 勉強会
http://www.postgresql.jp/wg/shikumi/shikumi25/

PostgreSQLアンカンファレンス@東京
http://atnd.org/events/35310

Published in: Technology

使ってみませんか?pg hint_plan

  1. 1. 使ってみませんか? pg_hint_plan 2013年2月16日 NTTデータ 基盤システム事業本部 第25回しくみ+アプリケーション勉強会 PostgreSQLアンカンファレンス@東京Copyright © 2013 NTT DATA Corporation
  2. 2. 目次  pg_hint_planの紹介  デモ  HINT句とコミュニティ  HINT句とNTTデータCopyright © 2013 NTT DATA Corporation 2
  3. 3. pg_hint_planの紹介Copyright © 2013 NTT DATA Corporation
  4. 4. pg_hint_planとは?PostgreSQLでHINT句を使えるようにする外部モジュール 開発元 NTT OSSセンタ 公開日 2012年12月 ライセンス BSD対応バージョン PostgreSQL9.1、9.2 公開先 http://en.sourceforge.jp/projects/pghintplan/ pg_hint_plan Copyright © 2013 NTT DATA Corporation 4
  5. 5. プランとは? SQLの実行方法にも複数ある PostgreSQLは、統計情報から最適な方法を選択してSQL実行 プランとは、SQLを実行する方法のこと どのようにSQL を実行するのが 最適だろう? シーケンシャルスキャン インデックススキャン 統計 情報 インデックスオンリースキャン Copyright © 2013 NTT DATA Corporation 5
  6. 6. プラン選択の課題どのプランを選ぶかはPostgreSQL任せ PostgreSQLが最適なプランを選んでくれなくて性能劣化 DBの状況変化に伴い、突然不適切なプランが選ばれて性能劣化商用DBは、プラン選択をDB任せにせず、ユーザに制御させる機能を提供 PostgreSQLではGUCパラメータである程度制御可能だが、柔軟でない 柔軟なプラン制御を外部ツールで実現 DBに指示(HINT)を与えて、どのプランを選ぶかユーザ HINT句 が思い通りに制御 → pg_hint_plan 統計情報 一度最適なプランを選んだら、ずっとそのプランを選ぶ の固定化 ように統計情報を固定化 → pg_dbms_stats Copyright © 2013 NTT DATA Corporation 6
  7. 7. HINT句のイメージ インデックススキャンを 選ぶように! シーケンシャルスキャンHINT インデックススキャン 選択 統計 情報 インデックスオンリースキャンCopyright © 2013 NTT DATA Corporation 7
  8. 8. pg_hint_planでのHINT句の指定HINT句は、クエリ先頭のブロックコメント /*+ ... */ 内に指定 クエリ先頭以外の/*+ */は、HINT句と見なされない商用DBとはHINT句の指定場所が異なるため注意 table1はシーケンシャルスキャン、 table2は主キーインデックスt2_pleyの /*+ インデックスキャンを指示するHINT句 SeqScan(t1) IndexScan(t2 t2_pkey) */ クエリ先頭以外の HINT句は無視される SELECT /*+ IndexScan(t1 t1_pkey) */ * FROM table1 t1 JOIN table2 t2 ON (t1.key = t2.key); Copyright © 2013 NTT DATA Corporation 8
  9. 9. pg_hint_planがサポートするHINT句の種類商用DBで特に使われるHINT句をサポート カテゴリ 説明 スキャン方法 テーブルをどの方法でスキャンするか? 結合方法 テーブルをどの方法で結合するか? 結合順序 テーブルをどの順序で結合するか? パラメータ設定 プラン作成中だけ使うパラメータ設定 Copyright © 2013 NTT DATA Corporation 9
  10. 10. pg_hint_planがサポートするHINT句の種類スキャン方法のHINT句 書式 説明SeqScan シーケンシャルスキャンを選択TidScan TIDスキャンを選択 インデックススキャンを選択IndexScan スキャンにどのインデックスを使うか指定可能 インデックスオンリースキャンを選択(PostgreSQL9.2以降)IndexOnlyScan スキャンにどのインデックスを使うか指定可能 ビットマップスキャンを選択BitmapScan スキャンにどのインデックスを使うか指定可能 Copyright © 2013 NTT DATA Corporation 10
  11. 11. pg_hint_planがサポートするHINT句の種類スキャン方法のHINT句 書式 説明NoSeqScan シーケンシャルスキャン以外で最小コストのスキャンを選択NoTidScan TIDスキャン以外で最小コストのスキャンを選択NoIndexScan インデックススキャン以外で最小コストのスキャンを選択 インデックスオンリースキャン以外で最小コストのスキャンを選択NoIndexOnlyScan (PostgreSQL9.2以降)NoBitmapScan ビットマップスキャン以外で最小コストのスキャンを選択 Copyright © 2013 NTT DATA Corporation 11
  12. 12. pg_hint_planがサポートするHINT句の種類結合方法のHINT句 書式 説明NestLoop ネストループ結合を選択HashJoin ハッシュ結合を選択MergeJoin マージ結合を選択NoNestLoop ネストループ結合以外で最小コストの結合を選択NoHashJoin ハッシュ結合以外で最小コストの結合を選択NoMergeJoin マージ結合以外で最小コストの結合を選択 Copyright © 2013 NTT DATA Corporation 12
  13. 13. pg_hint_planがサポートするHINT句の種類結合順序のHINT句 書式 説明Leading テーブルを指定した通りの順番で結合パラメータ設定のHINT句 書式 説明Set プラン作成中だけGUCパラメータを指定した値に変更 Copyright © 2013 NTT DATA Corporation 13
  14. 14. デモCopyright © 2013 NTT DATA Corporation
  15. 15. インストールと設定 インストールはいつものやり方 $ tar zxf pg_hint_plan92-1.0.0.tar.gz $ cd pg_hint_plan92-1.0.0 $ make ※USE_PGXS=1を未指定でも自動的にpgxsを使ってビルド $ su # make install PostgreSQLがpg_hint_planをロードするようにパラメータ設定 $ vi $PGDATA/postgresql.conf shared_preload_libraries = pg_hint_plan ※custom_variable_classesはv9.2以降廃止されたため、設定不要 Copyright © 2013 NTT DATA Corporation 15
  16. 16. HINT句お試し 単純なSQLでHINT句を使用 =# CREATE TABLE hoge (a int, b int); =# INSERT INTO hoge SELECT x, x FROM generate_series(1,10000) x; =# CREATE INDEX aaa_idx ON hoge (a); =# CREATE INDEX bbb_idx ON hoge (b); =# VACUUM ANALYZE hoge; =# EXPLAIN ANALYZE SELECT * FROM hoge WHERE a < 9000 AND b > 10; /*+ BitmapScan(hoge) */ /*+ SeqScan(hoge) */ /*+ IndexScan(hoge aaa_idx) */ /*+ IndexScan(hoge bbb_idx) */ Copyright © 2013 NTT DATA Corporation 16
  17. 17. HINT句お試し 複雑なSQLでHINT句を使用  不適切なプランが選ばれた例としてコミュニティで報告されていたものをデモ用 に変更  http://www.postgresql.org/message-id/E1TSyAf-0006st- DI@wrigleys.postgresql.org ID、値段、個数の3列を持つ商品テーブルをイメージ  id列は、ランダムな英数字10文字  price列は、0~10万のランダムな数字  num列は、0~10のランダムな数字 or NULL =# CREATE TABLE goods (id text primary key, price int, num int); =# (10万件のデータ挿入) =# CREATE INDEX goods_price_idx ON goods(price); =# VACUUM ANALYZE goods; Copyright © 2013 NTT DATA Corporation 17
  18. 18. HINT句お試し 複雑なSQLでHINT句を使用 /*+ HashJoin(goods ANY_subquery) */ EXPLAIN ANALYZE SELECT * HINT句未指定だと、プランナが不適切なプランを選択して、 低性能 FROM 現状プランナのよい改善案はなく、WITH句を使ったSQLに goods 書き換えることで問題を回避する必要がある WHERE id IN ( SELECT id FROM goods ORDER BY price LIMIT 605 ) AND num IS NULL 値段が安い商品605件のうち ORDER BY 在庫がない(個数がNULLである)商品で 最も値段が高い商品を price DESC 1件だけ検索する LIMIT 1; Copyright © 2013 NTT DATA Corporation 18
  19. 19. pg_hint_planの制約HINT句で制御できないケース HINT句で選択できるプランは、プランナが選択候補として挙げられるプランのみ  インデックス未定義の場合、インデックススキャンを選択できない  FULL OUTER JOINでは、ネストループ結合は選択できないPL/pgSQLにおける制限 PL/pgSQL関数内のクエリに直接HINT句を指定しても無視される 関数実行時のSELECTにHINT句を指定すること ただし、関数内のクエリがそのまま実行されるとは限らないため、HINT句が期待どお り動作するかは保証外ドキュメントに、制約が詳細に列挙されているため、 pg_hint_plan利用時には読んでおくこと! Copyright © 2013 NTT DATA Corporation 19
  20. 20. HINT句とコミュニティCopyright © 2013 NTT DATA Corporation
  21. 21. HINT句とPostgreSQLコミュニティhttp://wiki.postgresql.org/wiki/OptimizerHintsDiscussion Copyright © 2013 NTT DATA Corporation 21
  22. 22. HINT句に対するコミュニティのスタンスPostgreSQLがHINT句をサポートすることを、長年多くの人々が望んできたが、コミュニティの現在の公式なスタンスは、 他DBと同じやり方でHINT句を実装することに興味がない 「他DBにはあるから、PostgreSQLにもあるべき」という提案は歓迎しな い 他DBのHINT句には問題がある。問題を改善するアイデアがあるなら、 価値ある議論ができるかも Copyright © 2013 NTT DATA Corporation 22
  23. 23. コミュニティが考えるHINT句の問題 アプリケーションのコードがメンテナンスしにくくなる。クエリに指定され たHINT句は、多大なリファクタリングを必要とする アップグレードを邪魔する。今日役立ってるHINT句は、アップグレード後 に性能劣化の原因になるかもしれない DBAが、真の問題を解決する代わりに、HINT句に頼り切ってしまう。こ の悪い癖をHINT句は助長する HINT句はデータサイズに対してスケールしない。テーブルが小さいとき に正しかったHINTは、大きくなったときに間違ってしまう PostgreSQLのプランナの改善を邪魔する。HINT句の利用者は、クエリ の問題をコミュニティに報告しなくなる Copyright © 2013 NTT DATA Corporation 23
  24. 24. コミュニティが考えるHINT句の使いどころ メンテナンス性を気にする必要のない単発クエリ 様々なプランをテストして、プランナがどう動くのか見るための方法 プランナのバグの対策  既知の実装上のバグ  理論上の問題。プラン見積もりの上限など Copyright © 2013 NTT DATA Corporation 24
  25. 25. HINT句とNTTデータCopyright © 2013 NTT DATA Corporation
  26. 26. NTTデータがHINT句を必要とする理由性能の安定化 基幹系システムでは、最高性能より性能の安定性の方が重要 プランが変化することによる突然の性能向上/劣化を避けたいHINT句でプランを固定化し、性能を安定化させたい!クエリチューニングの(最終)手段 どう頑張っても最適なプランを選んでくれないクエリのチューニング プランナのバグは修正済だが、マイナーバージョンのリリースまで時間が あり、システム開発に間に合わない場合のチューニング商用DBからPostgreSQLへのマイグレーションの促進HINT句のリスクは承知済。リスクのシステムへの影響を見切った上で利用 Copyright © 2013 NTT DATA Corporation 26
  27. 27. まとめCopyright © 2013 NTT DATA Corporation
  28. 28. まとめ HINT句は使い方次第で 魔法の杖にも トラブルの元凶にもなります。 効果とリスクを正しく理解し、 pg_hint_planで PostgreSQLの一歩進んだ使い方を!Copyright © 2013 NTT DATA Corporation 28
  29. 29. Copyright © 2011 NTT DATA CorporationCopyright © 2013 NTT DATA Corporation

×