29
Copyright © 2013 NTT DATA Corporation 2013年2月16日 NTTデータ 基盤システム事業本部 使ってみませんか? pg_hint_plan PostgreSQLアンカンファレンス@東京 第25回しくみ+アプリケーション勉強会

使ってみませんか?pg hint_plan

Embed Size (px)

DESCRIPTION

第25回しくみ+アプリケーション 勉強会 http://www.postgresql.jp/wg/shikumi/shikumi25/ PostgreSQLアンカンファレンス@東京 http://atnd.org/events/35310

Citation preview

Page 1: 使ってみませんか?pg hint_plan

Copyright © 2013 NTT DATA Corporation

2013年2月16日 NTTデータ 基盤システム事業本部

使ってみませんか? pg_hint_plan

PostgreSQLアンカンファレンス@東京

第25回しくみ+アプリケーション勉強会

Page 2: 使ってみませんか?pg hint_plan

2 Copyright © 2013 NTT DATA Corporation

目次

pg_hint_planの紹介

デモ

HINT句とコミュニティ

HINT句とNTTデータ

Page 3: 使ってみませんか?pg hint_plan

Copyright © 2013 NTT DATA Corporation 3

pg_hint_planの紹介

Page 4: 使ってみませんか?pg hint_plan

4 Copyright © 2013 NTT DATA Corporation

pg_hint_planとは?

PostgreSQLでHINT句を使えるようにする外部モジュール

開発元 NTT OSSセンタ

公開日 2012年12月

ライセンス BSD

対応バージョン PostgreSQL9.1、9.2

公開先 http://en.sourceforge.jp/projects/pghintplan/

pg_hint_plan

Page 5: 使ってみませんか?pg hint_plan

5 Copyright © 2013 NTT DATA Corporation

統計情報

プランとは?

シーケンシャルスキャン

インデックススキャン

インデックスオンリースキャン

SQLの実行方法にも複数ある

PostgreSQLは、統計情報から最適な方法を選択してSQL実行

プランとは、SQLを実行する方法のこと

どのようにSQLを実行するのが最適だろう?

Page 6: 使ってみませんか?pg hint_plan

6 Copyright © 2013 NTT DATA Corporation

プラン選択の課題

どのプランを選ぶかはPostgreSQL任せ

PostgreSQLが最適なプランを選んでくれなくて性能劣化

DBの状況変化に伴い、突然不適切なプランが選ばれて性能劣化

商用DBは、プラン選択をDB任せにせず、ユーザに制御させる機能を提供

PostgreSQLではGUCパラメータである程度制御可能だが、柔軟でない

柔軟なプラン制御を外部ツールで実現

HINT句

統計情報 の固定化

DBに指示(HINT)を与えて、どのプランを選ぶかユーザが思い通りに制御 → pg_hint_plan

一度最適なプランを選んだら、ずっとそのプランを選ぶように統計情報を固定化 → pg_dbms_stats

Page 7: 使ってみませんか?pg hint_plan

7 Copyright © 2013 NTT DATA Corporation

統計情報

HINT句のイメージ

シーケンシャルスキャン

インデックススキャン

インデックスオンリースキャン

インデックススキャンを選ぶように!

HINT

選択

Page 8: 使ってみませんか?pg hint_plan

8 Copyright © 2013 NTT DATA Corporation

pg_hint_planでのHINT句の指定

HINT句は、クエリ先頭のブロックコメント /*+ ... */ 内に指定

クエリ先頭以外の/*+ */は、HINT句と見なされない

商用DBとはHINT句の指定場所が異なるため注意

/*+

SeqScan(t1)

IndexScan(t2 t2_pkey)

*/

SELECT /*+ IndexScan(t1 t1_pkey) */

* FROM table1 t1 JOIN table2 t2 ON (t1.key = t2.key);

table1はシーケンシャルスキャン、table2は主キーインデックスt2_pleyの インデックスキャンを指示するHINT句

クエリ先頭以外のHINT句は無視される

Page 9: 使ってみませんか?pg hint_plan

9 Copyright © 2013 NTT DATA Corporation

pg_hint_planがサポートするHINT句の種類

商用DBで特に使われるHINT句をサポート

カテゴリ 説明

スキャン方法 テーブルをどの方法でスキャンするか?

結合方法 テーブルをどの方法で結合するか?

結合順序 テーブルをどの順序で結合するか?

パラメータ設定 プラン作成中だけ使うパラメータ設定

Page 10: 使ってみませんか?pg hint_plan

10 Copyright © 2013 NTT DATA Corporation

pg_hint_planがサポートするHINT句の種類

スキャン方法のHINT句

書式 説明

SeqScan シーケンシャルスキャンを選択

TidScan TIDスキャンを選択

IndexScan インデックススキャンを選択 スキャンにどのインデックスを使うか指定可能

IndexOnlyScan インデックスオンリースキャンを選択(PostgreSQL9.2以降) スキャンにどのインデックスを使うか指定可能

BitmapScan ビットマップスキャンを選択 スキャンにどのインデックスを使うか指定可能

Page 11: 使ってみませんか?pg hint_plan

11 Copyright © 2013 NTT DATA Corporation

pg_hint_planがサポートするHINT句の種類

スキャン方法のHINT句

書式 説明

NoSeqScan シーケンシャルスキャン以外で最小コストのスキャンを選択

NoTidScan TIDスキャン以外で最小コストのスキャンを選択

NoIndexScan インデックススキャン以外で最小コストのスキャンを選択

NoIndexOnlyScan インデックスオンリースキャン以外で最小コストのスキャンを選択 (PostgreSQL9.2以降)

NoBitmapScan ビットマップスキャン以外で最小コストのスキャンを選択

Page 12: 使ってみませんか?pg hint_plan

12 Copyright © 2013 NTT DATA Corporation

pg_hint_planがサポートするHINT句の種類

結合方法のHINT句

書式 説明

NestLoop ネストループ結合を選択

HashJoin ハッシュ結合を選択

MergeJoin マージ結合を選択

NoNestLoop ネストループ結合以外で最小コストの結合を選択

NoHashJoin ハッシュ結合以外で最小コストの結合を選択

NoMergeJoin マージ結合以外で最小コストの結合を選択

Page 13: 使ってみませんか?pg hint_plan

13 Copyright © 2013 NTT DATA Corporation

pg_hint_planがサポートするHINT句の種類

結合順序のHINT句

パラメータ設定のHINT句

書式 説明

Leading テーブルを指定した通りの順番で結合

書式 説明

Set プラン作成中だけGUCパラメータを指定した値に変更

Page 14: 使ってみませんか?pg hint_plan

Copyright © 2013 NTT DATA Corporation 14

デモ

Page 15: 使ってみませんか?pg hint_plan

15 Copyright © 2013 NTT DATA Corporation

インストールと設定

インストールはいつものやり方

$ 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以降廃止されたため、設定不要

Page 16: 使ってみませんか?pg hint_plan

16 Copyright © 2013 NTT DATA Corporation

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) */

Page 17: 使ってみませんか?pg hint_plan

17 Copyright © 2013 NTT DATA Corporation

HINT句お試し

複雑なSQLでHINT句を使用

不適切なプランが選ばれた例としてコミュニティで報告されていたものをデモ用に変更

http://www.postgresql.org/message-id/[email protected]

=# CREATE TABLE goods (id text primary key, price int, num int);

=# (10万件のデータ挿入)

=# CREATE INDEX goods_price_idx ON goods(price);

=# VACUUM ANALYZE goods;

ID、値段、個数の3列を持つ商品テーブルをイメージ id列は、ランダムな英数字10文字 price列は、0~10万のランダムな数字 num列は、0~10のランダムな数字 or NULL

Page 18: 使ってみませんか?pg hint_plan

18 Copyright © 2013 NTT DATA Corporation

HINT句お試し

複雑なSQLでHINT句を使用

/*+ HashJoin(goods ANY_subquery) */

EXPLAIN ANALYZE

SELECT

*

FROM

goods

WHERE

id IN ( SELECT id FROM goods ORDER BY price LIMIT 605 )

AND

num IS NULL

ORDER BY

price DESC

LIMIT 1;

値段が安い商品605件のうち 在庫がない(個数がNULLである)商品で 最も値段が高い商品を 1件だけ検索する

HINT句未指定だと、プランナが不適切なプランを選択して、低性能 現状プランナのよい改善案はなく、WITH句を使ったSQLに書き換えることで問題を回避する必要がある

Page 19: 使ってみませんか?pg hint_plan

19 Copyright © 2013 NTT DATA Corporation

pg_hint_planの制約

HINT句で制御できないケース HINT句で選択できるプランは、プランナが選択候補として挙げられるプランのみ

インデックス未定義の場合、インデックススキャンを選択できない

FULL OUTER JOINでは、ネストループ結合は選択できない

PL/pgSQLにおける制限 PL/pgSQL関数内のクエリに直接HINT句を指定しても無視される

関数実行時のSELECTにHINT句を指定すること

ただし、関数内のクエリがそのまま実行されるとは限らないため、HINT句が期待どおり動作するかは保証外

ドキュメントに、制約が詳細に列挙されているため、

pg_hint_plan利用時には読んでおくこと!

Page 20: 使ってみませんか?pg hint_plan

Copyright © 2013 NTT DATA Corporation 20

HINT句とコミュニティ

Page 21: 使ってみませんか?pg hint_plan

21 Copyright © 2013 NTT DATA Corporation

HINT句とPostgreSQLコミュニティ

http://wiki.postgresql.org/wiki/OptimizerHintsDiscussion

Page 22: 使ってみませんか?pg hint_plan

22 Copyright © 2013 NTT DATA Corporation

HINT句に対するコミュニティのスタンス

PostgreSQLがHINT句をサポートすることを、長年多くの人々が望んできたが、コミュニティの現在の公式なスタンスは、

他DBと同じやり方でHINT句を実装することに興味がない

「他DBにはあるから、PostgreSQLにもあるべき」という提案は歓迎しない

他DBのHINT句には問題がある。問題を改善するアイデアがあるなら、価値ある議論ができるかも

Page 23: 使ってみませんか?pg hint_plan

23 Copyright © 2013 NTT DATA Corporation

コミュニティが考えるHINT句の問題

アプリケーションのコードがメンテナンスしにくくなる。クエリに指定されたHINT句は、多大なリファクタリングを必要とする

アップグレードを邪魔する。今日役立ってるHINT句は、アップグレード後に性能劣化の原因になるかもしれない

DBAが、真の問題を解決する代わりに、HINT句に頼り切ってしまう。この悪い癖をHINT句は助長する

HINT句はデータサイズに対してスケールしない。テーブルが小さいときに正しかったHINTは、大きくなったときに間違ってしまう

PostgreSQLのプランナの改善を邪魔する。HINT句の利用者は、クエリの問題をコミュニティに報告しなくなる

Page 24: 使ってみませんか?pg hint_plan

24 Copyright © 2013 NTT DATA Corporation

コミュニティが考えるHINT句の使いどころ

メンテナンス性を気にする必要のない単発クエリ

様々なプランをテストして、プランナがどう動くのか見るための方法

プランナのバグの対策 既知の実装上のバグ

理論上の問題。プラン見積もりの上限など

Page 25: 使ってみませんか?pg hint_plan

Copyright © 2013 NTT DATA Corporation 25

HINT句とNTTデータ

Page 26: 使ってみませんか?pg hint_plan

26 Copyright © 2013 NTT DATA Corporation

NTTデータがHINT句を必要とする理由

性能の安定化

基幹系システムでは、最高性能より性能の安定性の方が重要

プランが変化することによる突然の性能向上/劣化を避けたい

HINT句でプランを固定化し、性能を安定化させたい!

クエリチューニングの(最終)手段

どう頑張っても最適なプランを選んでくれないクエリのチューニング

プランナのバグは修正済だが、マイナーバージョンのリリースまで時間があり、システム開発に間に合わない場合のチューニング

商用DBからPostgreSQLへのマイグレーションの促進

HINT句のリスクは承知済。リスクのシステムへの影響を見切った上で利用

Page 27: 使ってみませんか?pg hint_plan

Copyright © 2013 NTT DATA Corporation 27

まとめ

Page 28: 使ってみませんか?pg hint_plan

28 Copyright © 2013 NTT DATA Corporation

まとめ

HINT句は使い方次第で

魔法の杖にも

トラブルの元凶にもなります。

効果とリスクを正しく理解し、

pg_hint_planで

PostgreSQLの一歩進んだ使い方を!

Page 29: 使ってみませんか?pg hint_plan

Copyright © 2011 NTT DATA Corporation

Copyright © 2013 NTT DATA Corporation