railsネタです
kaminariが重い
kaminariとは言わずと知れたRubyのページネーションライブラリ。Railsとの親和性が非常に高く、ソースコードをちょちょっと弄るだけで難しいページネーションが作れる。
が、ページネーション対象のデータの件数が多いと(10万件超えとか)、表示にすごく時間がかかるようになってしまう。
(171006.2ms) SELECT COUNT(*) FROM `posts` Rendered posts/index.html.erb within layouts/application (172073.0ms) Completed 200 OK in 172318ms (Views: 172092.3ms | ActiveRecord: 171666.5ms)
え。。。
原因
重い原因はcount(*)
そもそもページネーションするのに全体の件数が必要なので、kiminariは自動でselect count(*)
を毎回実行せざる得ない。
が、巨大レコードになるとselect count(*)
が辛くなる。。よって重くなるのである。
対策
比較的最近だが、それ専用のオプションができた。without_count
をつけてあげる。
例えば以下の例だと、
@posts = Post.order("datetime desc").page(params[:page]).per(20)
こんな感じ
@posts = Post.order("datetime desc").page(params[:page]).without_count.per(20)
するとkaminariはselect count(*)
をしなくなる。
が、それだと当然今までのページネーションもできなくなるので、
<%= paginate(@posts) %>
を
<%= link_to_prev_page @posts, '前のページ' %> <%= link_to_next_page @posts, '次のページ' %>
等に書き換える必要がある。