diff options
author | Xavier Noria <fxn@hashref.com> | 2011-12-04 11:29:56 -0800 |
---|---|---|
committer | Xavier Noria <fxn@hashref.com> | 2011-12-04 11:52:12 -0800 |
commit | cfeac38e2b149d39edeb9add452fbd2ff96679b9 (patch) | |
tree | daf7620f621f0d533298acb31710ae6261f49760 /activerecord/lib/active_record/explain_subscriber.rb | |
parent | 5dfdc69ef91bf946ec55184053bdd7a167f7b9f1 (diff) | |
download | rails-cfeac38e2b149d39edeb9add452fbd2ff96679b9.tar.gz rails-cfeac38e2b149d39edeb9add452fbd2ff96679b9.tar.bz2 rails-cfeac38e2b149d39edeb9add452fbd2ff96679b9.zip |
implements a much faster auto EXPLAIN, closes #3843 [José Valim & Xavier Noria]
This commit vastly reduces the impact of auto
explain logging when enabled, while keeping
a negligible cost when disabled.
The first implementation was based on the idea
of subscribing to "sql.active_record" when
needed, and unsubscribing once done. This is
the idea behind AR::Relation#explain. Subscribe,
collect, unsubscribe.
But with the current implementation of notifications
unsubscribing is costly, because it wipes an internal
cache and that puts a penalty on the next event.
So we are switching to an approach where a long-running
subscriber is listening. Instead of collecting the
queries with a closure in a dedicated subscriber, now
we setup a thread local.
If the feature is disabled by setting the threshold
to nil, the subscriber will call a method that does
nothing. That's totally cheap.
Diffstat (limited to 'activerecord/lib/active_record/explain_subscriber.rb')
-rw-r--r-- | activerecord/lib/active_record/explain_subscriber.rb | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/activerecord/lib/active_record/explain_subscriber.rb b/activerecord/lib/active_record/explain_subscriber.rb new file mode 100644 index 0000000000..8a88be6761 --- /dev/null +++ b/activerecord/lib/active_record/explain_subscriber.rb @@ -0,0 +1,13 @@ +module ActiveRecord + class ExplainSubscriber < ActiveSupport::LogSubscriber + def sql(event) + ActiveRecord::Base.collect_queries_for_explain(event.payload) + end + + def logger + ActiveRecord::Base.logger + end + + attach_to :active_record + end +end |