Copyright© 2014 NTT Software Corporation. All rights reserved.
PostgreSQL
インデックス・チューニング
NTTソフトウェア株式会社
クラウド事業部
勝俣 智成
2014/6/19
2Copyright© 2014 NTT Software Corporation. All rights reserved.
Agenda
• インデックスとは?
• PostgreSQLで使えるインデックス
• B-treeインデックス
• ハッシュインデックス
• GiSTインデックス
• SP-GiSTインデックス
• GINインデックス
• B-treeインデックスチューニング
• インデックスのサイズ計算
• 使われているインデックスの確認方法
• 複数列インデックス、一意インデックス、式インデックス、部
分インデックス
• 効果的な利用
3Copyright© 2014 NTT Software Corporation. All rights reserved.
自己紹介
勝俣 智成(かつまた ともなり)
NTTソフトウェア株式会社 主任エンジニア
経歴
2002年同社入社。
数年間は全文検索に関する業務を担当。
PostgreSQLとの出会いは2004年。
PostgreSQLに全文検索機能やXML検索機能などを拡張する開発に従事。
以降、開発・国内外のPostgreSQLカンファレンスへの参加、社内外での
PostgreSQL研修の講師などを行っている。
4Copyright© 2014 NTT Software Corporation. All rights reserved.
インデックスとは?
5Copyright© 2014 NTT Software Corporation. All rights reserved.
インデックスとは?
• まずは、インデックスについておさらいしていきます
• インデックスの必要性?
• インデックスがない状態でテーブルをスキャンすると、
テーブルのすべての行をチェックして必要なデータを取得
しなければいけない
• 事前にスキャンのための準備(=インデックスを作成)して
おくことで、効率的なスキャンを行うことができる
インデックスがないので、
全行チェック…
インデックスがあると、
効率よくデータを取得できる!
6Copyright© 2014 NTT Software Corporation. All rights reserved.
インデックスとは?
• インデックスは万能ではない?
• 対象のテーブルが小さい場合は、インデックスを利用しな
い(全件スキャンのほうが効率的なので)
• 取得するデータが多い場合は、インデックスを利用しない
(全件スキャンのほうが効率的なので)
• インデックスの更新を伴うため、更新時のオーバヘッドも
考慮しないといけない(不要なインデックスはいらない)
7Copyright© 2014 NTT Software Corporation. All rights reserved.
PostgreSQLで使える
インデックス
8Copyright© 2014 NTT Software Corporation. All rights reserved.
PostgreSQLで使えるインデックス
• 続いて、PostgreSQLで利用可能なインデックスの特徴につい
て、それぞれ確認していきます
• B-treeインデックス
• ハッシュインデックス
• GiSTインデックス
• SP-GiSTインデックス
• GINインデックス
9Copyright© 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つの
テーブルデータをポイント
10Copyright© 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に
記録されない。
• データベースクラッシュ後には再構築が必要
• レプリケーションではスタンバイへの伝搬がされない
現在利用は推奨されていません!
11Copyright© 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
• 残念ながら、サイズメリットもない模様
12Copyright© 2014 NTT Software Corporation. All rights reserved.
PostgreSQLで使えるインデックス
• GiSTインデックス
• 汎用検索ツリー(Generalized Search Tree)で、均衡なツ
リー構造のインデックスを表す
• カリフォルニア大学バークレイ校のGiSTプロジェクトから
派生
• どのような演算子に対応するかは、インデックスの実装依
存
• PostgreSQLではGiSTを用いてインデックスを実装するため
の基本的なテンプレートが提供されるが、contribパッ
ケージとして同梱されたモジュールや外部モジュールでも
利用できる
• ltree … 階層ツリー
• hstore … キー:バリュー型
• pg_trgm … 全文検索
• PostGIS … 地理情報
13Copyright© 2014 NTT Software Corporation. All rights reserved.
PostgreSQLで使えるインデックス
• SP-GiSTインデックス
• Space-Partitioned GiSTの略で、非均衡なツリー構造のイ
ンデックスを表す
• Purdue大学のSP-GiSTプロジェクトから派生
• 元々はメモリ上での操作を想定されていたが、ディスク
ベースの操作も効果的に行えるよう実装されている
• PostgreSQLでは以下が含まれている
• text … 基数木インデックス
• point … 四分木インデックス、k-d木インデックス
14Copyright© 2014 NTT Software Corporation. All rights reserved.
PostgreSQLで使えるインデックス
• GINインデックス
• 汎用転置インデックス(Generalized Inverted Index)
• 全文検索用のインデックス構築で広く利用されている
• PostgreSQLに同梱されているpg_trgmや日本語対応した全
文検索モジュールpg_bigm(*)などで利用できる
(*) http://pgbigm.sourceforge.jp/
1つのエントリは複数の
テーブルデータをポイント
15Copyright© 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
利用方針に適したインデックスを作成するとよい!
16Copyright© 2014 NTT Software Corporation. All rights reserved.
PostgreSQLで使えるインデックス
インデックスの種類 主な用途 補足
B-treeインデックス 汎用的に利用できる
ハッシュインデックス 非推奨 WALを書かない
サイズも大きい
利用するメリットはない
GiSTインデックス 地理情報向け
全文検索向け
SP-GiSTインデックス 地理情報向け GiSTと比べ、非均一な
データで優位?
GINインデックス 全文検索向け
17Copyright© 2014 NTT Software Corporation. All rights reserved.
B-treeインデックス
チューニング
18Copyright© 2014 NTT Software Corporation. All rights reserved.
B-treeインデックスチューニング
• ここからは汎用的に利用されるB-treeインデックスに着目し、以下
の点を確認していきます
• インデックスサイズの計算方法
• 使われているインデックスの確認方法
• インデックスの応用利用
• 複数列インデックス
• 一意インデックス
• 式インデックス
• 部分インデックス
• インデックスの効果的な利用
• HOT更新とインデックス
• Index Only Scan
19Copyright© 2014 NTT Software Corporation. All rights reserved.
インデックスサイズの計算方法
B-treeインデックスのサイズを計算するため、下記を整理し
ていきます
 B-treeインデックスのファイル構造
 B-treeインデックスのファイルレイアウト
これらを踏まえ、具体的なファイルサイズの見積もりを行ってい
きます
20Copyright© 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構造
物理ファイル
21Copyright© 2014 NTT Software Corporation. All rights reserved.
B-treeインデックスのファイルレイアウト
インデックスファイルのレイアウト
ページヘッダ
ラインポインタ1
ラインポインタ2
...
FreeSpace
...
タプル2
タプル1
24Bytes
pd_lower
pd_upper
4Bytes×タプル数
BLCKSZ
(通常8kB)
ページ
(メタ)
ページ
(インターナル/リーフ)
ページ
ページ
ページ
ページ
ページ
インデックスファイル
ページ
16BytesSpacialSpace
タプルヘッダ:8Bytes
データサイズ:可変長
↓
(8+可変長)Bytes×タプル数
22Copyright© 2014 NTT Software Corporation. All rights reserved.
B-treeインデックスのサイズ見積もり
B-treeインデックス容量見積もり方
 インデックス定義(DDL)から1エントリあたりのデータサイ
ズを算出する
-タプルヘッダ分のデータも考慮すること
 1リーフページ(8192Byte)に何エントリ分のデータが格納
可能か算出する
-FILLFACTORの分も考慮すること(リーフのデフォルト
90%)
 想定するエントリを格納するのに必要なリーフページ数を
算出する
 全てのリーフページをカバーするために必要なルートペー
ジおよびインターナルページ数を算出する
-ルートページ、インターナルページのFILLFACTORは70%
固定
23Copyright© 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(総サイズ)
24Copyright© 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 共有バッファからブロックを読み込んだ回数
25Copyright© 2014 NTT Software Corporation. All rights reserved.
インデックスの応用利用
複数列インデックス
 その名の通り、複数の列に対するインデックスを作成する
 検索時に、常に一緒に条件式として用いられる複数の列に対して作成
しておくと効果的
 複数列で一意性制約を付与できるのであればなおよい
 PostgreSQLでは、B-tree、GiST、GINインデックスで、それぞれ32列
までの複数列インデックスを作成できる
一意インデックス
 (複数の)列が一意であることを保証したインデックス
 一意インデックスを定義できるのはB-treeインデックスのみ
 NULLは異なるものとして扱われる
 PostgreSQLでは、プライマリーキーもしくは一意性制約を付与した列
に対し、暗黙的に一意インデックスを作成する
- →プライマリーキーもしくは一意性制約を付与した列に対して、別途イン
デックスを定義する必要はない
26Copyright© 2014 NTT Software Corporation. All rights reserved.
インデックスの応用利用
式インデックス
 エントリとして、テーブルの列を直接指定するのではなく、列の値を
元にした演算結果を用いたインデックス
 INSERT/UPDATE/DELETEに対しては、相対的に遅くなる(演算を実行す
るため)が、SELECTは高速になる
- →更新頻度と参照頻度を顧みたご利用を!
部分インデックス
 インデックスサイズの縮小や問い合わせに対し適切なインデックスの
利用を試行させるため、一部の列値に対して作成するインデックス
 CREATE INDEX文にWHERE句で条件を指定して作成する
 条件として指定できるのは、インデックス対象となる列でなくても構
わない
- →しかし問い合わせの際には、作成時に指定した条件も一緒に指定するこ
とが必要
27Copyright© 2014 NTT Software Corporation. All rights reserved.
インデックスの効果的な利用
HOT更新とインデックス
 PostgreSQL8.3からHOT更新と呼ばれる仕組みが備わった
 HOT更新とはHeap Only Tupleの略で、更新時にテーブルだけを更新
することで、更新性能を上げるもの
 HOT更新は自動的になされるが、以下の両方を満たしたUPDATE文に
よる更新の必要がある
- インデックスを定義した列を更新しない
- テーブル上の更新データは同一ページに格納される
UPDATE!
テーブルのポインタを
差し替える
インデックスの更新はしない!
28Copyright© 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がまったく
増加していないインデックスは削除できないか検討する
定義したインデックスは検索で使われてなければ、
足かせにしかならない。無駄なインデックスは削除!
29Copyright© 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
30Copyright© 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
ページのデータ全てが可視かどうかすぐ分かる
31Copyright© 2014 NTT Software Corporation. All rights reserved.
まとめ
本資料では、以下のことを整理した
 一般的なインデックスのメリット/デメリット
 PostgreSQLで利用できるインデックス種類
 PostgreSQLでB-treeインデックスを効果的に用いる方法
システムに合わせ、
インデックスの特色を活かした運用を!
32Copyright© 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
33Copyright© 2014 NTT Software Corporation. All rights reserved.
ご清聴ありがとうございました。
■お問い合わせ■
NTTソフトウェア株式会社 ソフト道場
https://www.ntts.co.jp/qs/soft_dojyo.html

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

  • 1.
    Copyright© 2014 NTTSoftware Corporation. All rights reserved. PostgreSQL インデックス・チューニング NTTソフトウェア株式会社 クラウド事業部 勝俣 智成 2014/6/19
  • 2.
    2Copyright© 2014 NTTSoftware Corporation. All rights reserved. Agenda • インデックスとは? • PostgreSQLで使えるインデックス • B-treeインデックス • ハッシュインデックス • GiSTインデックス • SP-GiSTインデックス • GINインデックス • B-treeインデックスチューニング • インデックスのサイズ計算 • 使われているインデックスの確認方法 • 複数列インデックス、一意インデックス、式インデックス、部 分インデックス • 効果的な利用
  • 3.
    3Copyright© 2014 NTTSoftware Corporation. All rights reserved. 自己紹介 勝俣 智成(かつまた ともなり) NTTソフトウェア株式会社 主任エンジニア 経歴 2002年同社入社。 数年間は全文検索に関する業務を担当。 PostgreSQLとの出会いは2004年。 PostgreSQLに全文検索機能やXML検索機能などを拡張する開発に従事。 以降、開発・国内外のPostgreSQLカンファレンスへの参加、社内外での PostgreSQL研修の講師などを行っている。
  • 4.
    4Copyright© 2014 NTTSoftware Corporation. All rights reserved. インデックスとは?
  • 5.
    5Copyright© 2014 NTTSoftware Corporation. All rights reserved. インデックスとは? • まずは、インデックスについておさらいしていきます • インデックスの必要性? • インデックスがない状態でテーブルをスキャンすると、 テーブルのすべての行をチェックして必要なデータを取得 しなければいけない • 事前にスキャンのための準備(=インデックスを作成)して おくことで、効率的なスキャンを行うことができる インデックスがないので、 全行チェック… インデックスがあると、 効率よくデータを取得できる!
  • 6.
    6Copyright© 2014 NTTSoftware Corporation. All rights reserved. インデックスとは? • インデックスは万能ではない? • 対象のテーブルが小さい場合は、インデックスを利用しな い(全件スキャンのほうが効率的なので) • 取得するデータが多い場合は、インデックスを利用しない (全件スキャンのほうが効率的なので) • インデックスの更新を伴うため、更新時のオーバヘッドも 考慮しないといけない(不要なインデックスはいらない)
  • 7.
    7Copyright© 2014 NTTSoftware Corporation. All rights reserved. PostgreSQLで使える インデックス
  • 8.
    8Copyright© 2014 NTTSoftware Corporation. All rights reserved. PostgreSQLで使えるインデックス • 続いて、PostgreSQLで利用可能なインデックスの特徴につい て、それぞれ確認していきます • B-treeインデックス • ハッシュインデックス • GiSTインデックス • SP-GiSTインデックス • GINインデックス
  • 9.
    9Copyright© 2014 NTTSoftware 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.
    10Copyright© 2014 NTTSoftware 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.
    11Copyright© 2014 NTTSoftware 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.
    12Copyright© 2014 NTTSoftware Corporation. All rights reserved. PostgreSQLで使えるインデックス • GiSTインデックス • 汎用検索ツリー(Generalized Search Tree)で、均衡なツ リー構造のインデックスを表す • カリフォルニア大学バークレイ校のGiSTプロジェクトから 派生 • どのような演算子に対応するかは、インデックスの実装依 存 • PostgreSQLではGiSTを用いてインデックスを実装するため の基本的なテンプレートが提供されるが、contribパッ ケージとして同梱されたモジュールや外部モジュールでも 利用できる • ltree … 階層ツリー • hstore … キー:バリュー型 • pg_trgm … 全文検索 • PostGIS … 地理情報
  • 13.
    13Copyright© 2014 NTTSoftware Corporation. All rights reserved. PostgreSQLで使えるインデックス • SP-GiSTインデックス • Space-Partitioned GiSTの略で、非均衡なツリー構造のイ ンデックスを表す • Purdue大学のSP-GiSTプロジェクトから派生 • 元々はメモリ上での操作を想定されていたが、ディスク ベースの操作も効果的に行えるよう実装されている • PostgreSQLでは以下が含まれている • text … 基数木インデックス • point … 四分木インデックス、k-d木インデックス
  • 14.
    14Copyright© 2014 NTTSoftware Corporation. All rights reserved. PostgreSQLで使えるインデックス • GINインデックス • 汎用転置インデックス(Generalized Inverted Index) • 全文検索用のインデックス構築で広く利用されている • PostgreSQLに同梱されているpg_trgmや日本語対応した全 文検索モジュールpg_bigm(*)などで利用できる (*) http://pgbigm.sourceforge.jp/ 1つのエントリは複数の テーブルデータをポイント
  • 15.
    15Copyright© 2014 NTTSoftware 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.
    16Copyright© 2014 NTTSoftware Corporation. All rights reserved. PostgreSQLで使えるインデックス インデックスの種類 主な用途 補足 B-treeインデックス 汎用的に利用できる ハッシュインデックス 非推奨 WALを書かない サイズも大きい 利用するメリットはない GiSTインデックス 地理情報向け 全文検索向け SP-GiSTインデックス 地理情報向け GiSTと比べ、非均一な データで優位? GINインデックス 全文検索向け
  • 17.
    17Copyright© 2014 NTTSoftware Corporation. All rights reserved. B-treeインデックス チューニング
  • 18.
    18Copyright© 2014 NTTSoftware Corporation. All rights reserved. B-treeインデックスチューニング • ここからは汎用的に利用されるB-treeインデックスに着目し、以下 の点を確認していきます • インデックスサイズの計算方法 • 使われているインデックスの確認方法 • インデックスの応用利用 • 複数列インデックス • 一意インデックス • 式インデックス • 部分インデックス • インデックスの効果的な利用 • HOT更新とインデックス • Index Only Scan
  • 19.
    19Copyright© 2014 NTTSoftware Corporation. All rights reserved. インデックスサイズの計算方法 B-treeインデックスのサイズを計算するため、下記を整理し ていきます  B-treeインデックスのファイル構造  B-treeインデックスのファイルレイアウト これらを踏まえ、具体的なファイルサイズの見積もりを行ってい きます
  • 20.
    20Copyright© 2014 NTTSoftware 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.
    21Copyright© 2014 NTTSoftware Corporation. All rights reserved. B-treeインデックスのファイルレイアウト インデックスファイルのレイアウト ページヘッダ ラインポインタ1 ラインポインタ2 ... FreeSpace ... タプル2 タプル1 24Bytes pd_lower pd_upper 4Bytes×タプル数 BLCKSZ (通常8kB) ページ (メタ) ページ (インターナル/リーフ) ページ ページ ページ ページ ページ インデックスファイル ページ 16BytesSpacialSpace タプルヘッダ:8Bytes データサイズ:可変長 ↓ (8+可変長)Bytes×タプル数
  • 22.
    22Copyright© 2014 NTTSoftware Corporation. All rights reserved. B-treeインデックスのサイズ見積もり B-treeインデックス容量見積もり方  インデックス定義(DDL)から1エントリあたりのデータサイ ズを算出する -タプルヘッダ分のデータも考慮すること  1リーフページ(8192Byte)に何エントリ分のデータが格納 可能か算出する -FILLFACTORの分も考慮すること(リーフのデフォルト 90%)  想定するエントリを格納するのに必要なリーフページ数を 算出する  全てのリーフページをカバーするために必要なルートペー ジおよびインターナルページ数を算出する -ルートページ、インターナルページのFILLFACTORは70% 固定
  • 23.
    23Copyright© 2014 NTTSoftware 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.
    24Copyright© 2014 NTTSoftware 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.
    25Copyright© 2014 NTTSoftware Corporation. All rights reserved. インデックスの応用利用 複数列インデックス  その名の通り、複数の列に対するインデックスを作成する  検索時に、常に一緒に条件式として用いられる複数の列に対して作成 しておくと効果的  複数列で一意性制約を付与できるのであればなおよい  PostgreSQLでは、B-tree、GiST、GINインデックスで、それぞれ32列 までの複数列インデックスを作成できる 一意インデックス  (複数の)列が一意であることを保証したインデックス  一意インデックスを定義できるのはB-treeインデックスのみ  NULLは異なるものとして扱われる  PostgreSQLでは、プライマリーキーもしくは一意性制約を付与した列 に対し、暗黙的に一意インデックスを作成する - →プライマリーキーもしくは一意性制約を付与した列に対して、別途イン デックスを定義する必要はない
  • 26.
    26Copyright© 2014 NTTSoftware Corporation. All rights reserved. インデックスの応用利用 式インデックス  エントリとして、テーブルの列を直接指定するのではなく、列の値を 元にした演算結果を用いたインデックス  INSERT/UPDATE/DELETEに対しては、相対的に遅くなる(演算を実行す るため)が、SELECTは高速になる - →更新頻度と参照頻度を顧みたご利用を! 部分インデックス  インデックスサイズの縮小や問い合わせに対し適切なインデックスの 利用を試行させるため、一部の列値に対して作成するインデックス  CREATE INDEX文にWHERE句で条件を指定して作成する  条件として指定できるのは、インデックス対象となる列でなくても構 わない - →しかし問い合わせの際には、作成時に指定した条件も一緒に指定するこ とが必要
  • 27.
    27Copyright© 2014 NTTSoftware Corporation. All rights reserved. インデックスの効果的な利用 HOT更新とインデックス  PostgreSQL8.3からHOT更新と呼ばれる仕組みが備わった  HOT更新とはHeap Only Tupleの略で、更新時にテーブルだけを更新 することで、更新性能を上げるもの  HOT更新は自動的になされるが、以下の両方を満たしたUPDATE文に よる更新の必要がある - インデックスを定義した列を更新しない - テーブル上の更新データは同一ページに格納される UPDATE! テーブルのポインタを 差し替える インデックスの更新はしない!
  • 28.
    28Copyright© 2014 NTTSoftware 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.
    29Copyright© 2014 NTTSoftware 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.
    30Copyright© 2014 NTTSoftware 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.
    31Copyright© 2014 NTTSoftware Corporation. All rights reserved. まとめ 本資料では、以下のことを整理した  一般的なインデックスのメリット/デメリット  PostgreSQLで利用できるインデックス種類  PostgreSQLでB-treeインデックスを効果的に用いる方法 システムに合わせ、 インデックスの特色を活かした運用を!
  • 32.
    32Copyright© 2014 NTTSoftware 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.
    33Copyright© 2014 NTTSoftware Corporation. All rights reserved. ご清聴ありがとうございました。 ■お問い合わせ■ NTTソフトウェア株式会社 ソフト道場 https://www.ntts.co.jp/qs/soft_dojyo.html