Module: ActiveRecord::Explain
Class Method Summary collapse
Instance Method Summary collapse
-
#collecting_queries_for_explain ⇒ Object
Relation#explain needs to be able to collect the queries regardless of whether auto explain is enabled.
-
#exec_explain(queries) ⇒ Object
Makes the adapter execute EXPLAIN for the tuples of queries and bindings.
-
#logging_query_plan ⇒ Object
The available_queries_for_explain thread variable collects the queries to be explained.
-
#silence_auto_explain ⇒ Object
Silences automatic EXPLAIN logging for the duration of the block.
Class Method Details
.extended(base) ⇒ Object
5 6 7 8 9 10 11 12 |
# File 'lib/active_record/explain.rb', line 5 def self.extended(base) base.class_eval do # If a query takes longer than these many seconds we log its query plan # automatically. nil disables this feature. class_attribute :auto_explain_threshold_in_seconds, :instance_writer => false self.auto_explain_threshold_in_seconds = nil end end |
Instance Method Details
#collecting_queries_for_explain ⇒ Object
Relation#explain needs to be able to collect the queries regardless of whether auto explain is enabled. This method serves that purpose.
47 48 49 50 51 52 53 54 |
# File 'lib/active_record/explain.rb', line 47 def collecting_queries_for_explain # :nodoc: current = Thread.current original, current[:available_queries_for_explain] = current[:available_queries_for_explain], [] return yield, current[:available_queries_for_explain] ensure # Note that the return value above does not depend on this assigment. current[:available_queries_for_explain] = original end |
#exec_explain(queries) ⇒ Object
Makes the adapter execute EXPLAIN for the tuples of queries and bindings. Returns a formatted string ready to be logged.
58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/active_record/explain.rb', line 58 def exec_explain(queries) # :nodoc: queries && queries.map do |sql, bind| [].tap do |msg| msg << "EXPLAIN for: #{sql}" unless bind.empty? bind_msg = bind.map {|col, val| [col.name, val]}.inspect msg.last << " #{bind_msg}" end msg << connection.explain(sql, bind) end.join("\n") end.join("\n") end |
#logging_query_plan ⇒ Object
The available_queries_for_explain thread variable collects the queries to be explained. If the value is nil, it means queries are not being currently collected. A false value indicates collecting is turned off. Otherwise it is an array of queries.
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/active_record/explain.rb', line 25 def logging_query_plan # :nodoc: return yield unless logger threshold = auto_explain_threshold_in_seconds current = Thread.current if connection.supports_explain? && threshold && current[:available_queries_for_explain].nil? begin queries = current[:available_queries_for_explain] = [] start = Time.now result = yield logger.warn(exec_explain(queries)) if Time.now - start > threshold result ensure current[:available_queries_for_explain] = nil end else yield end end |
#silence_auto_explain ⇒ Object
Silences automatic EXPLAIN logging for the duration of the block.
This has high priority, no EXPLAINs will be run even if downwards the threshold is set to 0.
As the name of the method suggests this only applies to automatic EXPLAINs, manual calls to ActiveRecord::Relation#explain run.
78 79 80 81 82 83 84 |
# File 'lib/active_record/explain.rb', line 78 def silence_auto_explain current = Thread.current original, current[:available_queries_for_explain] = current[:available_queries_for_explain], false yield ensure current[:available_queries_for_explain] = original end |