index-only (別名 index covering)

tgkさんのとこで、PostgreSQLは「インデックスだけ見てデータは見ない」ということができないらしいという話があり、これが気になっていました。

まさかと思っていたのですが、どうやらそうみたい。
postgresql-8.3.5の配布物にTODOというファイルがあるのですが、そこにこうあります。

* Allow data to be pulled directly from indexes

  Currently indexes do not have enough tuple visibility information
  to allow data to be pulled from the index without also accessing
  the heap.  One way to allow this is to set a bit on index tuples
  to indicate if a tuple is currently visible to all transactions
  when the first valid heap lookup happens.  This bit would have to
  be cleared when a heap tuple is expired.

  Another idea is to maintain a bitmap of heap pages where all rows
  are visible to all backends, and allow index lookups to reference
  that bitmap to avoid heap lookups, perhaps the same bitmap we might
  add someday to determine which heap pages need vacuuming.  Frequently
  accessed bitmaps would have to be stored in shared memory.  One 8k
  page of bitmaps could track 512MB of heap pages.

  A third idea would be for a heap scan to check if all rows are visible
  and if so set a per-table flag which can be checked by index scans. 
  Any change to the table would have to clear the flag.  To detect
  changes during the heap scan a counter could be set at the start and
  checked at the end --- if it is the same, the table has not been
  modified --- any table change would increment the counter.

トランザクションが絡んだときのタプル(行)の可視性の関係でまだ実現できていないみたいですね。

どのRDBMSでも使えるパフォーマンスチューニングの手段だと思ってたのにちょっと残念。そうはいってもPostgreSQLで使えないことがどれくらいのデメリットなのかどうかまだ判断できてません。いずれちゃんと確認したいところです。


ところで、「インデックスだけ見てデータは見ない」機能なんですが、一言でバシッと言えないとわかりにくいですよね。下の本ではindex-onlyと呼んでいます。教科書として使われている本らしいのでこれに倣えばいいよね。これからはindex-onlyと呼んでいこうと思います。(MySQLSQL Serverではindex coveringとかcovering indexとか呼んでいますけどね。)

Database Management Systems

そういえば、T字形ERもINDEX-onlyと呼んでいましたね(indexが大文字というところがちょっとちがう)。

データベース設計論 T字形ER―関係モデルとオジブェクト指向の統合をめざして