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 していないのでよくわからず。
コメント
コメントを投稿