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. ユーザーが自力でがんばる
自力でがんばるのがなんだかんだいっても安全確実ではあります。