class Dblint::Checks::MissingIndex
Public Instance Methods
statement_finished(_name, _id, _payload)
click to toggle source
# File lib/dblint/checks/missing_index.rb, line 16 def statement_finished(_name, _id, _payload) # Ignored end
statement_started(_name, _id, payload)
click to toggle source
# File lib/dblint/checks/missing_index.rb, line 6 def statement_started(_name, _id, payload) return if payload[:sql].include?(';') return unless payload[:sql].starts_with?('SELECT') ActiveRecord::Base.connection.execute 'SET enable_seqscan = off', 'DBLINT' plan = explain(payload) raise_on_seqscan(plan[0]['Plan'], payload) ActiveRecord::Base.connection.execute 'SET enable_seqscan = on', 'DBLINT' end
Private Instance Methods
explain(payload)
click to toggle source
# File lib/dblint/checks/missing_index.rb, line 22 def explain(payload) plan = ActiveRecord::Base.connection.select_value(format('EXPLAIN (FORMAT JSON) %s', payload[:sql]), 'DBLINT', payload[:binds]) JSON.parse(plan) end
raise_on_seqscan(plan, payload)
click to toggle source
# File lib/dblint/checks/missing_index.rb, line 28 def raise_on_seqscan(plan, payload) if plan['Node Type'] == 'Seq Scan' && plan['Filter'].present? main_app_caller = find_main_app_caller(caller) return unless main_app_caller.present? return if ignored?(main_app_caller) error_msg = format("Missing index on %s for '%s' in '%s', called by %s", plan['Relation Name'], plan['Filter'], payload[:sql], main_app_caller) raise Error, error_msg end (plan['Plans'] || []).each do |subplan| raise_on_seqscan(subplan, payload) end end