Class::DBI は search / search_like / retrieve_all など複数の検索結果を取得するメソッドにおいて、
my $it = Music::CD->search_like(title => 'October%');
while (my $cd = $it->next) {
print $cd->title;
}
と Iterator で取得できるにもかかわらず、実際の実装は全件を取得してそれを回しています。Iterator と言えば、集合から要素を取り出す際に一件ずつ、必要な分だけ取得するという実装が多いため、Class::DBI の Iterator もそうなっているかと思いきや、実はそうではない罠があります。何も意識せずに使っていると、大量の結果があるけど実際には表示にはちょっとしか使わない、というケースでパフォーマンスを損することになります。(その代表例がページング処理ですね。「2000件中 10 件を表示」とか。)
この Iterator の実装を、本来の Iterator の実装にしてしまいましょうと、浅倉さんがプラグインを公開されています。
ちゃんと1件ずつ取得するようなIteratorを作ってみた。
http://asakura.g.hatena.ne.jp/asakura-t/20041218 (紹介)
http://asakura.g.hatena.ne.jp/asakura-t/20041219 (ダウンロード)
http://asakura.g.hatena.ne.jp/asakura-t/20041220 (TIPS)
もともと Class::DBI::Pager における実装の限界 (ページング処理にもかかわらず全件取得) を改善するために作られたプラグインのようで、Class::DBI::Plugin::Pager を使わず、且つ既存のコードにはほとんど手を入れずに、ページング処理のパフォーマンスを上げることができるという点がポイントのようです。
FeedBack にも導入してみようかな。ちなむと、CPAN に up 希望です。