【RubyOnRails】 will_paginate+ransackを組み合わせたらソートが遅くなった


ruby 2.1.1
rails 4.1.6
will_paginate 3.0.3
ransack 1.6.6

色んなテーブルを連結した検索を行っている状況で、ransackのソート機能を使用したらajaxを利用しているのにページの取得がすごく重くなってしまいました。
確認したところデータの取得が遅かったがindexは問題なかった。

ひとつ目の原因は外部結合でつなげたテーブルのカラムでソートをかけたこと。
7個ぐらいテーブルを結合しているのでそりゃ重くなるよな。
でもこれはソートしないことには意味がないのでどうしようもなかった。

んで、解決方法をどうしたかというとwill_paginateのtotal_entriesをパラメータに指定して解決しました。

articles_count = articles.count
articles = articles.meta_sort # 外部結合したカラムでソートする処理
articles.paginate(:total_entries => articles_count, :page => params[:page], :per_page => @per_page)   

will_paginateは全体の件数(total_entries)を取得して、それをページネーションに使用しています。
この全体の件数を取得するSQLにソート用のテーブルが結合されていたため2500msもかかるSQLになっていました。
全体の件数はソートしておく必要がないので、ソート用のテーブルが結合される前の段階で件数を取得しtotal_entriesにセットするようにしました。

結果2500msかかっていたSQLが11.2msになり、無事問題解決しました。

参考にしたのはこちら
http://makandracards.com/makandra/6513-will_paginate-on-complex-scopes-may-be-slow-workaround

解決してよかった。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です