最近Tokyo Cabinet(正確にはTokyo Tyrant経由でTokyo Cabinet)のテーブルデータベースを使っているんですが、どうも検索が遅いなぁと思ったらインデックスを張り忘れてて、Tokyo (Cabinet|Tyrant)でどうやってインデックスを張るのかを調べたので、そのまとめです。

実際にTCのテーブルデータベースでインデックスをどう張るのかというと、foo.tctってDBのnameってカラムにインデックスを張るとすると
% tctmgr setindex foo.tct name
ってやればOK。実際には張るインデックスのタイプが選べますが、その辺はドキュメントに載っていますのでそちらをご覧ください。

PerlモジュールのTokyoCabinetを使って張る場合は、
my $tdb = TokyoCabinet::TDB->new;
$tdb->open("foo.tct", $tdb->OWRITER | $tdb->OCREAT);
$tdb->setindex("name", $tdb->ITLEXICAL);
ってやるだけでOK。

Tokyo Tyrant経由でもTokyoTyrant::RDBTBLにsetindex()って関数があるのでそれでインデックスが張れます。

また、Tokyo Tyrantのttserverでテーブルを指定して起動する際にも
% ttserver "foo.tct#idx=name:lex"
って感じにファイル名のあとに指定することもできるみたい。
いろいろな張り方があるんですねぇ。

ちなみインデックスを張るとfoo.tctとは別に「foo.tct.idx.name.lex」ってファイルが出来ます。どうやらここにインデックスが入ってるようです。
ファイル名がどのDBのどのカラムにどんなタイプのインデックスが張られているのか一目瞭然ですね!最後の.lexはインデックスのタイプですね。

で、ここまでわかって思ったのが、これって一度作成したらレコードがputされる毎に更新されるのか、わからなかったのでTokyo Cabinetのソースをみてみたらputされるタイミング(tctdbputimpl())でtctdbidxput()が呼ばれるようなので(両関数ともにtctdb.cの中)、一度作成作成しておけば、あとは勝手に更新されるようだ。

なるほどねぇ。
よくできてるなぁ。