インデクス

pgsql-hackersでの議論 [HACKERS] Much Ado About COUNT(*)
ちゃんと読んでるわけじゃないけど何となく内容はわかる気がする(だけかも?)。PGの(no overwrite storageシステムの)最大の弱点の一つ、インデクスデータを見ただけではそれの指し示しているデータがvisibleかどうかわからないので、visibilityチェック以外必要なくてもデータまで見なくてはならない、に関する問題である(らしい)。さてこれに関してBM氏が珍しく全く的外れとは言えない提案をしている(らしい)。現在インデクスデータには削除ビットが付加されていて、どう見てもデータが削除されている場合に(チャンスがあれば)立てることになっている。これを真似て新しい(最後の空き)ビットを使い、どうみても指し示すデータがvisibleであるインデクスデータに対してそのビットを立てたらどうかということだと思われる。勿論、彼の言うことだから十分に眉に唾しなければならない。似てはいるが非なる部分も大きいのだから。
一番大きな違いは削除ビットは一度オンにしたらオフる必要などないが、今回意図しているフラグは場合によっては何度もオンオフしなければならないということ。こういう種類のフラグ、私の経験では何故か、オンオフする仕組みをちゃんと作るスキルのない人が安易に導入しがちである。もう一つ大きな違いはこのフラグ、オンにする場合は出来たら(これは削除ビットも同様)でよいが、オフる場合は死んでもオフらねばならないということ。具体的に言えば、データの更新・削除の際に現実装では必要のないoldインデクスデータの更新を行いその更新に対するリカバリログを間違いなく取得しなければならなくなるということ。現実装でも、データ更新の際に値の変更があろうとなかろうとすべての関連インデクスデータを無条件に追加しなければならないというdisadvantage(他のDBMSに対する)があるのだが、それが更に大きなものになってしまうことになる。
これに対してメリットの方はどうなのだろう。新ビットの意図する所は、あるインデクスファイルのすべてのインデクスデータの新ビットか削除ビットが立っていれば対応するデータのvisibilityチェックを行う必要がなく件数カウントなどがインデクスファイルを読むだけですんでしまうということであろう。これはよいのだが、ほとんどのインデクスデータの新(そして削除)ビットがオフの場合はかえって悲惨な結果を招いてしまうのではなかろうか。結局インデクスファイルを全部とほとんどの対応データをランダムに読まざるを得なくなるからである。となると何らかの形でこのあたりを切り分けるための情報をもつ必要が出てくるであろう。そもそもこの新ビットが立つチャンスというのはどれほどあるのだろうか?新しくデータを挿入した直後というのは、そのデータに対するすべてのインデクスデータの新ビットはオフになっている。新ビットがオンになりうるのはそのインデクスデータと対応するデータを一緒に読む機会が発生した時である。これを隈なく実行する方法というのはvacuum位しか私には思いつかない、vacuumのタイミングの良し悪しに大きく依存することになるのだろうか?auto-vacuumはどんなタイミングで走ったのだったか?