active_scaffold の list 表示ではとりあえず JOIN するっぽい。

最近は Ruby on Rails のプラグイン active_scaffoldを使って管理ツールなんて作っているのですが。 ちょいとデータ量が増えたDBでリスト表示をしたところ、やたらにDBの検索に時間がかかる。 show full processlist をして稼働中クエリを見てみたところ、こんな感じ。


SELECT COUNT (table_a.id) FROM table_a
LEFT OUTER JOIN table_b ON table_b.table_a_id = table_a.id
WHERE table_a.boolean_fuga = false;

「むむ、もしや LEFT OUTER JOIN しているから遅い!?」と思い、こんなクエリをかけてみた。


SELECT COUNT (table_a.id) FROM table_a
WHERE table_a.boolean_fuga = false;

JOINをしないほうはさっさと終わった。


このSQL文だと別にJOINする必要はないので、JOINしているところを探してみた。この辺に原因があった。



vendor/plugins/active_scaffold/lib/active_scaffold/config/list.rb

attr_accessor :count_includes

vendor/plugins/active_scaffold/lib/active_scaffold/finder.rb

      options[:count_includes] ||= full_includes
klass = active_scaffold_config.model
# create a general-use options array that's compatible with Rails finders
finder_options = { :order => build_order_clause(options[:sorting]),
:conditions => all_conditions,
:joins => joins_for_finder,
:include => options[:count_includes]}


このリストを作るときのJOINする部分をなくす(JOINさせない)には、下記のように config.list.count_includes に空のArrayを設定すれば良いです。


active_scaffold :モデル do |config|
config.list.count_includes = []
end

MySQLのクエリプランナが、先に「WHERE table_a.boolean_fuga = false」を評価してくれれば良かったんですけどね。。 クエリプランナがどうなっていたのかは、まだ explain していないのでよくわからず。

コメント

このブログの人気の投稿

車両系建設機械運転者(整地) の講習

パスワードを覚えるのも無理があるから、パスワードマネージャ使いましょう。

大型特殊自動車免許を取った時の話。