[b23] postgresqlのインデックス・チューニング by tomonari katsumata
Post on 28-Nov-2014
1.228 Views
Preview:
DESCRIPTION
TRANSCRIPT
Copyright© 2014 NTT Software Corporation. All rights reserved.
PostgreSQL インデックス・チューニング
NTTソフトウェア株式会社 クラウド事業部 勝俣 智成
2014/6/19
2 Copyright© 2014 NTT Software Corporation. All rights reserved.
Agenda
• インデックスとは?
• PostgreSQLで使えるインデックス • B-treeインデックス
• ハッシュインデックス
• GiSTインデックス
• SP-GiSTインデックス
• GINインデックス
• B-treeインデックスチューニング • インデックスのサイズ計算
• 使われているインデックスの確認方法
• 複数列インデックス、一意インデックス、式インデックス、部分インデックス
• 効果的な利用
3 Copyright© 2014 NTT Software Corporation. All rights reserved.
自己紹介
勝俣 智成(かつまた ともなり) NTTソフトウェア株式会社 主任エンジニア
経歴 2002年同社入社。
数年間は全文検索に関する業務を担当。
PostgreSQLとの出会いは2004年。
PostgreSQLに全文検索機能やXML検索機能などを拡張する開発に従事。以降、開発・国内外のPostgreSQLカンファレンスへの参加、社内外でのPostgreSQL研修の講師などを行っている。
4 Copyright© 2014 NTT Software Corporation. All rights reserved.
インデックスとは?
5 Copyright© 2014 NTT Software Corporation. All rights reserved.
インデックスとは?
• まずは、インデックスについておさらいしていきます
• インデックスの必要性?
• インデックスがない状態でテーブルをスキャンすると、テーブルのすべての行をチェックして必要なデータを取得しなければいけない
• 事前にスキャンのための準備(=インデックスを作成)しておくことで、効率的なスキャンを行うことができる
インデックスがないので、
全行チェック…
インデックスがあると、
効率よくデータを取得できる!
6 Copyright© 2014 NTT Software Corporation. All rights reserved.
インデックスとは?
• インデックスは万能ではない?
• 対象のテーブルが小さい場合は、インデックスを利用しない(全件スキャンのほうが効率的なので)
• 取得するデータが多い場合は、インデックスを利用しない(全件スキャンのほうが効率的なので)
• インデックスの更新を伴うため、更新時のオーバヘッドも考慮しないといけない(不要なインデックスはいらない)
7 Copyright© 2014 NTT Software Corporation. All rights reserved.
PostgreSQLで使える インデックス
8 Copyright© 2014 NTT Software Corporation. All rights reserved.
PostgreSQLで使えるインデックス
• 続いて、PostgreSQLで利用可能なインデックスの特徴について、それぞれ確認していきます
• B-treeインデックス
• ハッシュインデックス
• GiSTインデックス
• SP-GiSTインデックス
• GINインデックス
9 Copyright© 2014 NTT Software Corporation. All rights reserved.
PostgreSQLで使えるインデックス
• B-treeインデックス
• PostgreSQLがデフォルトで作成するインデックス
• P. Lehman、S. Yaoによる「Efficient Locking for Concurrent Operations on B-Trees」をPostgreSQL向けに実装したもの
• 「>=,>,=,<,<=」の演算子で、完全一致検索、範囲検索を行う際に利用される
• 全てのデータ型に対してインデックスを作成でき、NULLや前方一致検索(LIKE ‘aaa%’)でも利用できる
1つのエントリは1つの
テーブルデータをポイント
10 Copyright© 2014 NTT Software Corporation. All rights reserved.
PostgreSQLで使えるインデックス
• ハッシュインデックス
• ハッシュ値比較を行うインデックス
• Margo SeltzerとOzan Yigitによる「A New Hashing Package for UNIX, Proceedings of the Winter USENIX Conference」をベースに実装したもの
• 「=」演算子のみで利用される
• PostgreSQL9.3現在、ハッシュインデックスの操作はWALに記録されない。 • データベースクラッシュ後には再構築が必要
• レプリケーションではスタンバイへの伝搬がされない
現在利用は推奨されていません!
11 Copyright© 2014 NTT Software Corporation. All rights reserved.
B-tree vs ハッシュ
• B-treeインデックスとハッシュインデックス
• ハッシュインデックスの利用はお勧めされていないことは前頁の通り
• とはいえ、サイズを極端に縮小できるなどのメリットがあれば、ハッシュインデックスを利用することも検討の余地があるかも?ということで確認
• 1000万件のinteger型カラムにB-tree、ハッシュそれぞれのインデックスを作成し、サイズを比較 [btree index size]
=# select pg_relation_size('bt_idx');
224641024 [hash index size]
=# select pg_relation_size('hash_idx');
268451840
• 残念ながら、サイズメリットもない模様
12 Copyright© 2014 NTT Software Corporation. All rights reserved.
PostgreSQLで使えるインデックス
• GiSTインデックス
• 汎用検索ツリー(Generalized Search Tree)で、均衡なツリー構造のインデックスを表す
• カリフォルニア大学バークレイ校のGiSTプロジェクトから派生
• どのような演算子に対応するかは、インデックスの実装依存
• PostgreSQLではGiSTを用いてインデックスを実装するための基本的なテンプレートが提供されるが、contribパッケージとして同梱されたモジュールや外部モジュールでも利用できる • ltree … 階層ツリー
• hstore … キー:バリュー型
• pg_trgm … 全文検索
• PostGIS … 地理情報
13 Copyright© 2014 NTT Software Corporation. All rights reserved.
PostgreSQLで使えるインデックス
• SP-GiSTインデックス
• Space-Partitioned GiSTの略で、非均衡なツリー構造のインデックスを表す
• Purdue大学のSP-GiSTプロジェクトから派生
• 元々はメモリ上での操作を想定されていたが、ディスクベースの操作も効果的に行えるよう実装されている
• PostgreSQLでは以下が含まれている • text … 基数木インデックス
• point … 四分木インデックス、k-d木インデックス
14 Copyright© 2014 NTT Software Corporation. All rights reserved.
PostgreSQLで使えるインデックス
• GINインデックス
• 汎用転置インデックス(Generalized Inverted Index)
• 全文検索用のインデックス構築で広く利用されている
• PostgreSQLに同梱されているpg_trgmや日本語対応した全文検索モジュールpg_bigm(*)などで利用できる
(*) http://pgbigm.sourceforge.jp/
1つのエントリは複数の
テーブルデータをポイント
15 Copyright© 2014 NTT Software Corporation. All rights reserved.
GiST vs GIN on FullTextSearch
• GiSTとGINはともに、pg_trgmで利用できる • どっちがよいの?という質問に答えるべく簡単な動作確認を実施
• 10万件のtextデータ(320byte)に対して、pg_trgmを用いてGiSTインデックス、GINインデックスを作成
• 構築時間、サイズ、検索時間を比較
GiST GIN
構築時間 11.83 [sec] 16.92 [sec]
サイズ 20 [MB] 48 [MB]
検索時間 57.46 [ms] 24.20 [ms]
上記の結果では、
構築時間、サイズを優先するならGiST、
検索速度を優先するならGIN
利用方針に適したインデックスを作成するとよい!
16 Copyright© 2014 NTT Software Corporation. All rights reserved.
PostgreSQLで使えるインデックス
インデックスの種類 主な用途 補足
B-treeインデックス 汎用的に利用できる
ハッシュインデックス 非推奨 WALを書かない
サイズも大きい
利用するメリットはない
GiSTインデックス 地理情報向け
全文検索向け
SP-GiSTインデックス 地理情報向け GiSTと比べ、非均一なデータで優位?
GINインデックス 全文検索向け
17 Copyright© 2014 NTT Software Corporation. All rights reserved.
B-treeインデックス チューニング
18 Copyright© 2014 NTT Software Corporation. All rights reserved.
B-treeインデックスチューニング
• ここからは汎用的に利用されるB-treeインデックスに着目し、以下の点を確認していきます
• インデックスサイズの計算方法
• 使われているインデックスの確認方法
• インデックスの応用利用
• 複数列インデックス
• 一意インデックス
• 式インデックス
• 部分インデックス
• インデックスの効果的な利用
• HOT更新とインデックス
• Index Only Scan
19 Copyright© 2014 NTT Software Corporation. All rights reserved.
インデックスサイズの計算方法
B-treeインデックスのサイズを計算するため、下記を整理していきます B-treeインデックスのファイル構造
B-treeインデックスのファイルレイアウト
これらを踏まえ、具体的なファイルサイズの見積もりを行っていきます
20 Copyright© 2014 NTT Software Corporation. All rights reserved.
B-treeインデックスのファイル構造
B-treeインデックスファイル
1ファイル最大1GB、データ量の増加にともないページ単位(8192byte)に増加していく
先頭の1ページ目はmetaデータページとして固定。その他のページがリーフページとインターナルページとして利用される
ページ1
ページ2
ページ3
ページ4
ページ1
ページ2 ページ3 ページ4
ページ5
・・・
ページn ページ5 ・・・ ページn ・・・
内部的にはB-Tree構造 物理ファイル
21 Copyright© 2014 NTT Software Corporation. All rights reserved.
B-treeインデックスのファイルレイアウト
インデックスファイルのレイアウト
ページヘッダ
ラインポインタ1
ラインポインタ2
...
FreeSpace
...
タプル2
タプル1
24Bytes
pd_lower
pd_upper
4Bytes×タプル数
BLCKSZ
(通常8kB)
ページ
(メタ)
ページ
(インターナル/リーフ)
ページ
ページ
ページ
ページ
ページ
インデックスファイル ページ
16Bytes SpacialSpace
タプルヘッダ:8Bytes
データサイズ:可変長
↓
(8+可変長)Bytes×タプル数
22 Copyright© 2014 NTT Software Corporation. All rights reserved.
B-treeインデックスのサイズ見積もり
B-treeインデックス容量見積もり方
インデックス定義(DDL)から1エントリあたりのデータサイズを算出する
-タプルヘッダ分のデータも考慮すること
1リーフページ(8192Byte)に何エントリ分のデータが格納可能か算出する
-FILLFACTORの分も考慮すること(リーフのデフォルト90%)
想定するエントリを格納するのに必要なリーフページ数を算出する
全てのリーフページをカバーするために必要なルートページおよびインターナルページ数を算出する
-ルートページ、インターナルページのFILLFACTORは70%固定
23 Copyright© 2014 NTT Software Corporation. All rights reserved.
B-treeインデックスのサイズ見積もり例
実際に、インデックスの見積もりをやってみよう。想定データは、1000万件、Integer型(4byte)、FILLFACTORはデフォルト(leaf=90%,その他=70%)
1エントリあたりのサイズ
- 4+4(+4)+8=20byte
1リーフページあたりのエントリ数
- floor(8192*90/100-24-16)=7332byte
- floor(7332/20)=366エントリ
必要なリーフページ数
- ceil(1000万/366)=27323ページ
- 27323*8192=223830016→223846400byte(メタ、ルートページ含む)
1インターナルページあたりのエントリ数
- floor(8192*70/100-24-16)=5694
- floor(5694/20)=284
必要なインターナルページ数
- ceil(27323/284)=97ページ
- 97*8192=794624→224641024byte(総サイズ)
24 Copyright© 2014 NTT Software Corporation. All rights reserved.
使われているインデックスの確認方法
定義したインデックスは検索で使われてなければ、足かせにしかならない
PostgreSQLの標準統計情報ビューを確認することで、インデックスの利用状況を把握できる
pg_stat_all_indexes
- インデックス毎のアクセスに関する統計情報を表示
- 使用されていないインデックスの特定が可能
pg_statio_all_indexes
- インデックス毎のI/Oに関する統計情報を表示
列名 概要
pg_stat_all_indexes列
idx_scan インデックススキャンの実行回数
idx_tup_read インデックススキャンで返されたノード数
idx_tup_fetch インデックススキャンで取り出されたレコード数
pg_statio_all_indexes列
idx_blks_read 共有バッファ以外からブロックを読み込んだ回数
idx_blks_hit 共有バッファからブロックを読み込んだ回数
25 Copyright© 2014 NTT Software Corporation. All rights reserved.
インデックスの応用利用
複数列インデックス その名の通り、複数の列に対するインデックスを作成する
検索時に、常に一緒に条件式として用いられる複数の列に対して作成しておくと効果的
複数列で一意性制約を付与できるのであればなおよい
PostgreSQLでは、B-tree、GiST、GINインデックスで、それぞれ32列までの複数列インデックスを作成できる
一意インデックス (複数の)列が一意であることを保証したインデックス
一意インデックスを定義できるのはB-treeインデックスのみ
NULLは異なるものとして扱われる
PostgreSQLでは、プライマリーキーもしくは一意性制約を付与した列に対し、暗黙的に一意インデックスを作成する
- →プライマリーキーもしくは一意性制約を付与した列に対して、別途インデックスを定義する必要はない
26 Copyright© 2014 NTT Software Corporation. All rights reserved.
インデックスの応用利用
式インデックス エントリとして、テーブルの列を直接指定するのではなく、列の値を元にした演算結果を用いたインデックス
INSERT/UPDATE/DELETEに対しては、相対的に遅くなる(演算を実行するため)が、SELECTは高速になる
- →更新頻度と参照頻度を顧みたご利用を!
部分インデックス インデックスサイズの縮小や問い合わせに対し適切なインデックスの利用を試行させるため、一部の列値に対して作成するインデックス
CREATE INDEX文にWHERE句で条件を指定して作成する
条件として指定できるのは、インデックス対象となる列でなくても構わない
- →しかし問い合わせの際には、作成時に指定した条件も一緒に指定することが必要
27 Copyright© 2014 NTT Software Corporation. All rights reserved.
インデックスの効果的な利用
HOT更新とインデックス
PostgreSQL8.3からHOT更新と呼ばれる仕組みが備わった
HOT更新とはHeap Only Tupleの略で、更新時にテーブルだけを更新することで、更新性能を上げるもの
HOT更新は自動的になされるが、以下の両方を満たしたUPDATE文による更新の必要がある
- インデックスを定義した列を更新しない
- テーブル上の更新データは同一ページに格納される
UPDATE!
テーブルのポインタを
差し替える
インデックスの更新はしない!
28 Copyright© 2014 NTT Software Corporation. All rights reserved.
インデックスの効果的な利用
HOT更新をできるだけ有効にするには
-pg_stat_all_tablesで、HOT更新の比率を確認可能
– n_tup_hot_upd / n_tup_upd
– HOT更新の比率が予想より小さい場合、不要なインデックスの存在がないか調査する
-前述のpg_stat_all_indexesを調査し、idx_scanがまったく増加していないインデックスは削除できないか検討する
定義したインデックスは検索で使われてなければ、
足かせにしかならない。無駄なインデックスは削除!
29 Copyright© 2014 NTT Software Corporation. All rights reserved.
Index Only Scan
PostgreSQLでもバージョン9.2からIndex Only Scanをサポート
• (特定の条件がそろえば)インデックスのみを走査して、結果を返すことが可能となる
• PostgreSQL9.1までは、インデックスの指し示すデータが実在するか判定するために、「実データ」を取得していた
• PostgreSQL9.2から、「visibility map」を利用し、インデックスの指し示すデータが実在するか判定するようになった
Index table あるかしら?
Index table あるかしら? VM
30 Copyright© 2014 NTT Software Corporation. All rights reserved.
Index Only Scan
Visibility mapとは?
テーブルの各ページがdead_tuple(削除/更新されてVACUUMされてない行)を含むか否かを表したフラグ
“visibility map”は、VACUUM実行時に作成/クリア(=全て可視)になり、更新/削除で不可視になる
• Index Only Scanでは、このvisibility mapを用いて、Indexだけスキャンすればよいか、テーブルまで見に行く必要があるかを判断
• ちなみにvisibility mapは、1bitで1ページの情報を表現できるので、すごく小さい。12345_vmみたいなファイルがvisibility mapファイル
Index Only Scanの恩恵を受けるなら、VACUUMのタイミングに
気を配ることも忘れずに!
table Visibility map 0 0 0
0 1 0 0 0 0
ページのデータ全てが可視かどうかすぐ分かる
31 Copyright© 2014 NTT Software Corporation. All rights reserved.
まとめ
本資料では、以下のことを整理した
一般的なインデックスのメリット/デメリット
PostgreSQLで利用できるインデックス種類
PostgreSQLでB-treeインデックスを効果的に用いる方法
システムに合わせ、
インデックスの特色を活かした運用を!
32 Copyright© 2014 NTT Software Corporation. All rights reserved.
参考文献
PostgreSQLオンラインマニュアル
インデックス
- http://www.postgresql.jp/document/9.3/html/indexes.html
GiST
- http://www.postgresql.jp/document/9.3/html/gist.html
SP-GiST
- http://www.postgresql.jp/document/9.3/html/spgist.html
GIN
- http://www.postgresql.jp/document/9.3/html/gin.html
33 Copyright© 2014 NTT Software Corporation. All rights reserved.
ご清聴ありがとうございました。
■お問い合わせ■
NTTソフトウェア株式会社 ソフト道場
https://www.ntts.co.jp/qs/soft_dojyo.html
top related