[b23] postgresqlのインデックス・チューニング by tomonari katsumata

33
Copyright© 2014 NTT Software Corporation. All rights reserved. PostgreSQL インデックス・チューニング NTTソフトウェア株式会社 クラウド事業部 勝俣 智成 2014/6/19

Upload: insight-technology-inc

Post on 28-Nov-2014

1.228 views

Category:

Technology


3 download

DESCRIPTION

 

TRANSCRIPT

Page 1: [B23] PostgreSQLのインデックス・チューニング by Tomonari Katsumata

Copyright© 2014 NTT Software Corporation. All rights reserved.

PostgreSQL インデックス・チューニング

NTTソフトウェア株式会社 クラウド事業部 勝俣 智成

2014/6/19

Page 2: [B23] PostgreSQLのインデックス・チューニング by Tomonari Katsumata

2 Copyright© 2014 NTT Software Corporation. All rights reserved.

Agenda

• インデックスとは?

• PostgreSQLで使えるインデックス • B-treeインデックス

• ハッシュインデックス

• GiSTインデックス

• SP-GiSTインデックス

• GINインデックス

• B-treeインデックスチューニング • インデックスのサイズ計算

• 使われているインデックスの確認方法

• 複数列インデックス、一意インデックス、式インデックス、部分インデックス

• 効果的な利用

Page 3: [B23] PostgreSQLのインデックス・チューニング by Tomonari Katsumata

3 Copyright© 2014 NTT Software Corporation. All rights reserved.

自己紹介

勝俣 智成(かつまた ともなり) NTTソフトウェア株式会社 主任エンジニア

経歴 2002年同社入社。

数年間は全文検索に関する業務を担当。

PostgreSQLとの出会いは2004年。

PostgreSQLに全文検索機能やXML検索機能などを拡張する開発に従事。以降、開発・国内外のPostgreSQLカンファレンスへの参加、社内外でのPostgreSQL研修の講師などを行っている。

Page 4: [B23] PostgreSQLのインデックス・チューニング by Tomonari Katsumata

4 Copyright© 2014 NTT Software Corporation. All rights reserved.

インデックスとは?

Page 5: [B23] PostgreSQLのインデックス・チューニング by Tomonari Katsumata

5 Copyright© 2014 NTT Software Corporation. All rights reserved.

インデックスとは?

• まずは、インデックスについておさらいしていきます

• インデックスの必要性?

• インデックスがない状態でテーブルをスキャンすると、テーブルのすべての行をチェックして必要なデータを取得しなければいけない

• 事前にスキャンのための準備(=インデックスを作成)しておくことで、効率的なスキャンを行うことができる

インデックスがないので、

全行チェック…

インデックスがあると、

効率よくデータを取得できる!

Page 6: [B23] PostgreSQLのインデックス・チューニング by Tomonari Katsumata

6 Copyright© 2014 NTT Software Corporation. All rights reserved.

インデックスとは?

• インデックスは万能ではない?

• 対象のテーブルが小さい場合は、インデックスを利用しない(全件スキャンのほうが効率的なので)

• 取得するデータが多い場合は、インデックスを利用しない(全件スキャンのほうが効率的なので)

• インデックスの更新を伴うため、更新時のオーバヘッドも考慮しないといけない(不要なインデックスはいらない)

Page 7: [B23] PostgreSQLのインデックス・チューニング by Tomonari Katsumata

7 Copyright© 2014 NTT Software Corporation. All rights reserved.

PostgreSQLで使える インデックス

Page 8: [B23] PostgreSQLのインデックス・チューニング by Tomonari Katsumata

8 Copyright© 2014 NTT Software Corporation. All rights reserved.

PostgreSQLで使えるインデックス

• 続いて、PostgreSQLで利用可能なインデックスの特徴について、それぞれ確認していきます

• B-treeインデックス

• ハッシュインデックス

• GiSTインデックス

• SP-GiSTインデックス

• GINインデックス

Page 9: [B23] PostgreSQLのインデックス・チューニング by Tomonari Katsumata

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つの

テーブルデータをポイント

Page 10: [B23] PostgreSQLのインデックス・チューニング by Tomonari Katsumata

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に記録されない。 • データベースクラッシュ後には再構築が必要

• レプリケーションではスタンバイへの伝搬がされない

現在利用は推奨されていません!

Page 11: [B23] PostgreSQLのインデックス・チューニング by Tomonari Katsumata

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

• 残念ながら、サイズメリットもない模様

Page 12: [B23] PostgreSQLのインデックス・チューニング by Tomonari Katsumata

12 Copyright© 2014 NTT Software Corporation. All rights reserved.

PostgreSQLで使えるインデックス

• GiSTインデックス

• 汎用検索ツリー(Generalized Search Tree)で、均衡なツリー構造のインデックスを表す

• カリフォルニア大学バークレイ校のGiSTプロジェクトから派生

• どのような演算子に対応するかは、インデックスの実装依存

• PostgreSQLではGiSTを用いてインデックスを実装するための基本的なテンプレートが提供されるが、contribパッケージとして同梱されたモジュールや外部モジュールでも利用できる • ltree … 階層ツリー

• hstore … キー:バリュー型

• pg_trgm … 全文検索

• PostGIS … 地理情報

Page 13: [B23] PostgreSQLのインデックス・チューニング by Tomonari Katsumata

13 Copyright© 2014 NTT Software Corporation. All rights reserved.

PostgreSQLで使えるインデックス

• SP-GiSTインデックス

• Space-Partitioned GiSTの略で、非均衡なツリー構造のインデックスを表す

• Purdue大学のSP-GiSTプロジェクトから派生

• 元々はメモリ上での操作を想定されていたが、ディスクベースの操作も効果的に行えるよう実装されている

• PostgreSQLでは以下が含まれている • text … 基数木インデックス

• point … 四分木インデックス、k-d木インデックス

Page 14: [B23] PostgreSQLのインデックス・チューニング by Tomonari Katsumata

14 Copyright© 2014 NTT Software Corporation. All rights reserved.

PostgreSQLで使えるインデックス

• GINインデックス

• 汎用転置インデックス(Generalized Inverted Index)

• 全文検索用のインデックス構築で広く利用されている

• PostgreSQLに同梱されているpg_trgmや日本語対応した全文検索モジュールpg_bigm(*)などで利用できる

(*) http://pgbigm.sourceforge.jp/

1つのエントリは複数の

テーブルデータをポイント

Page 15: [B23] PostgreSQLのインデックス・チューニング by Tomonari Katsumata

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

利用方針に適したインデックスを作成するとよい!

Page 16: [B23] PostgreSQLのインデックス・チューニング by Tomonari Katsumata

16 Copyright© 2014 NTT Software Corporation. All rights reserved.

PostgreSQLで使えるインデックス

インデックスの種類 主な用途 補足

B-treeインデックス 汎用的に利用できる

ハッシュインデックス 非推奨 WALを書かない

サイズも大きい

利用するメリットはない

GiSTインデックス 地理情報向け

全文検索向け

SP-GiSTインデックス 地理情報向け GiSTと比べ、非均一なデータで優位?

GINインデックス 全文検索向け

Page 17: [B23] PostgreSQLのインデックス・チューニング by Tomonari Katsumata

17 Copyright© 2014 NTT Software Corporation. All rights reserved.

B-treeインデックス チューニング

Page 18: [B23] PostgreSQLのインデックス・チューニング by Tomonari Katsumata

18 Copyright© 2014 NTT Software Corporation. All rights reserved.

B-treeインデックスチューニング

• ここからは汎用的に利用されるB-treeインデックスに着目し、以下の点を確認していきます

• インデックスサイズの計算方法

• 使われているインデックスの確認方法

• インデックスの応用利用

• 複数列インデックス

• 一意インデックス

• 式インデックス

• 部分インデックス

• インデックスの効果的な利用

• HOT更新とインデックス

• Index Only Scan

Page 19: [B23] PostgreSQLのインデックス・チューニング by Tomonari Katsumata

19 Copyright© 2014 NTT Software Corporation. All rights reserved.

インデックスサイズの計算方法

B-treeインデックスのサイズを計算するため、下記を整理していきます B-treeインデックスのファイル構造

B-treeインデックスのファイルレイアウト

これらを踏まえ、具体的なファイルサイズの見積もりを行っていきます

Page 20: [B23] PostgreSQLのインデックス・チューニング by Tomonari Katsumata

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構造 物理ファイル

Page 21: [B23] PostgreSQLのインデックス・チューニング by Tomonari Katsumata

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×タプル数

Page 22: [B23] PostgreSQLのインデックス・チューニング by Tomonari Katsumata

22 Copyright© 2014 NTT Software Corporation. All rights reserved.

B-treeインデックスのサイズ見積もり

B-treeインデックス容量見積もり方

インデックス定義(DDL)から1エントリあたりのデータサイズを算出する

-タプルヘッダ分のデータも考慮すること

1リーフページ(8192Byte)に何エントリ分のデータが格納可能か算出する

-FILLFACTORの分も考慮すること(リーフのデフォルト90%)

想定するエントリを格納するのに必要なリーフページ数を算出する

全てのリーフページをカバーするために必要なルートページおよびインターナルページ数を算出する

-ルートページ、インターナルページのFILLFACTORは70%固定

Page 23: [B23] PostgreSQLのインデックス・チューニング by Tomonari Katsumata

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(総サイズ)

Page 24: [B23] PostgreSQLのインデックス・チューニング by Tomonari Katsumata

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 共有バッファからブロックを読み込んだ回数

Page 25: [B23] PostgreSQLのインデックス・チューニング by Tomonari Katsumata

25 Copyright© 2014 NTT Software Corporation. All rights reserved.

インデックスの応用利用

複数列インデックス その名の通り、複数の列に対するインデックスを作成する

検索時に、常に一緒に条件式として用いられる複数の列に対して作成しておくと効果的

複数列で一意性制約を付与できるのであればなおよい

PostgreSQLでは、B-tree、GiST、GINインデックスで、それぞれ32列までの複数列インデックスを作成できる

一意インデックス (複数の)列が一意であることを保証したインデックス

一意インデックスを定義できるのはB-treeインデックスのみ

NULLは異なるものとして扱われる

PostgreSQLでは、プライマリーキーもしくは一意性制約を付与した列に対し、暗黙的に一意インデックスを作成する

- →プライマリーキーもしくは一意性制約を付与した列に対して、別途インデックスを定義する必要はない

Page 26: [B23] PostgreSQLのインデックス・チューニング by Tomonari Katsumata

26 Copyright© 2014 NTT Software Corporation. All rights reserved.

インデックスの応用利用

式インデックス エントリとして、テーブルの列を直接指定するのではなく、列の値を元にした演算結果を用いたインデックス

INSERT/UPDATE/DELETEに対しては、相対的に遅くなる(演算を実行するため)が、SELECTは高速になる

- →更新頻度と参照頻度を顧みたご利用を!

部分インデックス インデックスサイズの縮小や問い合わせに対し適切なインデックスの利用を試行させるため、一部の列値に対して作成するインデックス

CREATE INDEX文にWHERE句で条件を指定して作成する

条件として指定できるのは、インデックス対象となる列でなくても構わない

- →しかし問い合わせの際には、作成時に指定した条件も一緒に指定することが必要

Page 27: [B23] PostgreSQLのインデックス・チューニング by Tomonari Katsumata

27 Copyright© 2014 NTT Software Corporation. All rights reserved.

インデックスの効果的な利用

HOT更新とインデックス

PostgreSQL8.3からHOT更新と呼ばれる仕組みが備わった

HOT更新とはHeap Only Tupleの略で、更新時にテーブルだけを更新することで、更新性能を上げるもの

HOT更新は自動的になされるが、以下の両方を満たしたUPDATE文による更新の必要がある

- インデックスを定義した列を更新しない

- テーブル上の更新データは同一ページに格納される

UPDATE!

テーブルのポインタを

差し替える

インデックスの更新はしない!

Page 28: [B23] PostgreSQLのインデックス・チューニング by Tomonari Katsumata

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がまったく増加していないインデックスは削除できないか検討する

定義したインデックスは検索で使われてなければ、

足かせにしかならない。無駄なインデックスは削除!

Page 29: [B23] PostgreSQLのインデックス・チューニング by Tomonari Katsumata

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

Page 30: [B23] PostgreSQLのインデックス・チューニング by Tomonari Katsumata

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

ページのデータ全てが可視かどうかすぐ分かる

Page 31: [B23] PostgreSQLのインデックス・チューニング by Tomonari Katsumata

31 Copyright© 2014 NTT Software Corporation. All rights reserved.

まとめ

本資料では、以下のことを整理した

一般的なインデックスのメリット/デメリット

PostgreSQLで利用できるインデックス種類

PostgreSQLでB-treeインデックスを効果的に用いる方法

システムに合わせ、

インデックスの特色を活かした運用を!

Page 32: [B23] PostgreSQLのインデックス・チューニング by Tomonari Katsumata

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

Page 33: [B23] PostgreSQLのインデックス・チューニング by Tomonari Katsumata

33 Copyright© 2014 NTT Software Corporation. All rights reserved.

ご清聴ありがとうございました。

■お問い合わせ■

NTTソフトウェア株式会社 ソフト道場

https://www.ntts.co.jp/qs/soft_dojyo.html