tokuhirom's Blog

O/R Mapper におけるページャーの実装について

O/R Mapper においてはページャーの実装方法は3種類かんがえられます。

1. クエリから count(*) 文を発行して、勝手に Pager オブジェクトをつくる

採用しているO/R Mapper

DBIx::Class

利点

勝手に処理してくれるので楽。

欠点

$rs->pager();

のように、クエリをうっているっぽくないのに裏でうってるので、重い処理なのにおもそうにみえなくてさがすのが面倒。お気軽につかえすぎて危険。

HAVING などをつかうクエリの場合、そもそもただしい値がとれてないのに、なんとなくうごいてしまう。まちがった値をかえす API を標準でつけるのはいかがなものか。

得に HAVING などの処理がうまくできないのは自明なので、こういう実装は僕は好きではないです。
→ Teng にはついてない。

2. SQL_CALC_FOUND_ROWS をつかう

MySQL 限定。

利点

HAVING とかもうまくあつかえる。ちゃんとうごく。

欠点

MySQL でしかつかえない。

速度がなんか妙におそかったりするらしい。MySQL の実装がダメなのかもしれない。
(僕は速度がもとめられるケースでつかったことないのでしりません。)

3. 欲しい行数 + 1 とる

10行データがほしいときに LIMIT 11 して、11行目がとれたら次のページがあると判断する方式。

利点

一回のクエリですむ。はやい。

欠点

total の行数がとれないので、ページャーの表示具合に制限がある。が、こういうタイプのページャーをつかわなければならないほどでかいデータをあつかう必要がある場合、全体の件数を表示しても意味がない場合がおおいので、問題ないかとおもいます。

→ 僕は通常これをつかっています。

4. ユーザーが自力でがんばる

自力でがんばるのがなんだかんだいっても安全確実ではあります。