PostgreSQLで Index-Only

T字形サンプルアプリ作成の前段の作業として、PostgreSQLでIndex-onlyを実験中。
DOA+のレポート「非正規化すると本当に速いのか」は、DBMSPostgreSQLを使ってIndex-Onlyを実行した貴重な実例。
http://www.doaplus.com/html/bun03_20051101.html
ということは、PostgreSQLでIndex-onlyすることは可能ということだ。

Index-onlyとは、アクセスしたいデータをテーブルファイルではなくインデックスファイルのみから取得することで、高速レスポンスを可能にする技法。
参照したいカラムを全て含むマルチカラム・インデックスを作ればいいだけに思えるが、実際に高パフォーマンスを出すには、DBMSに以下の3点を強制しなくてはならない。

  1. 作成したインデックスを使わせる。
  2. データファイルにアクセスさせない。
  3. (もし大量データを返すクエリを実行したいなら)B-tree構造をいちいちルートから手繰らせず、末端のleafを"GetNext"させる(その方法はプロダクトごとに異なる)。

1.については、プランナがインデックスを使わずにSeq Scanしようとする場合は

set enable_seqscan to off;

をして、このセッションで一時的にSeq Scanを禁止すればよい。
が、あとの2.と3.をどうすればいいのかわかっていない。


2.については、PostgreSQLは、インデックスファイル上に必要なデータが揃っていても、データファイルにアクセスしてしまうことがわかっている。
そういう仕様になっている理由は、PostgreSQLアーキテクチャ上、インデックスが指す先の行がすでに削除済みになっているかもしれないから。
例えばここを読むと、最新バージョン(8.1)でもインデックスファイルへのアクセスだけでは済まないことががわかる:
PostgreSQLウォッチ】第17回 新しい実行プラン・タイプによるPostgreSQL 8.1の性能向上
http://itpro.nikkeibp.co.jp/members/ITPro/oss/20050514/160833/?ST=itpro_print

また、PostgreSQL開発者の間では、インデックスだけでデータを取得する機能が何度か検討されては立ち消えてきたらしい:
possible TODO: read-only tables, select from indexes only.
http://archives.postgresql.org/pgsql-hackers/2005-04/msg00660.php


3については、現時点では何もわかっていない。
とにかく、誠実にマニュアルを全部読むこと。話はそれからだな。