Class: Effective::QueryAnalyzer

Inherits:
Object
  • Object
show all
Defined in:
app/models/effective/query_analyzer.rb

Instance Method Summary collapse

Instance Method Details

#instrument_queries(ignore: []) ⇒ Object



3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'app/models/effective/query_analyzer.rb', line 3

def instrument_queries(ignore: [])
  ActiveSupport::Notifications.subscribe('sql.active_record') do |*args|
    event = ActiveSupport::Notifications::Event.new(*args)
    query = event.payload[:sql]
    name = args.last[:name]

    ignored_actions = ['EXPLAIN ANALYZE', 'BEGIN', 'COMMIT', 'ROLLBACK', 'SET']
    ignored_methods = ['SCHEMA', 'ActiveRecord::SchemaMigration Load']

    ignored = (event.duration < 1.0) # Ignore queries that take less than 1ms
    ignored ||= query.exclude?('WHERE') # We're only interested in queries that use a WHERE clause
    ignored ||= ignored_actions.any? { |action| query.start_with?(action) }
    ignored ||= ignored_methods.any? { |method| name.to_s.include?(method) }
    ignored ||= ignore.any? { |ignore| name.to_s.include?(ignore) }

    unless ignored
      # Get the execution plan
      plan = ActiveRecord::Base.logger.silence do
        ActiveRecord::Base.connection.execute("EXPLAIN ANALYZE #{query}").to_a.join("\n")
      end

      # Check for sequential scans
      if plan.include?('Seq Scan')
        Rails.logger.error "⚠️ Sequential Scan Detected (#{name}) ⚠️"
        Rails.logger.error "Query: #{query}"
        Rails.logger.error "Plan:\n#{plan}"
      end
    end
  end
end