Module: SqlSafetyNet::ExplainPlan::Mysql
- Defined in:
- lib/sql_safety_net/explain_plan/mysql.rb
Overview
Include this module in your MySQL connection class to analyze the query plan generated by MySQL.
Instance Method Summary collapse
Instance Method Details
#sql_safety_net_analyze_query_plan(sql, binds) ⇒ Object
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 |
# File 'lib/sql_safety_net/explain_plan/mysql.rb', line 5 def sql_safety_net_analyze_query_plan(sql, binds) alerts = [] config = SqlSafetyNet.config explain_results = select("EXPLAIN #{sql}", "EXPLAIN", binds) explain_results.each do |row| select_type = (row['select_type'] || '').downcase type = (row['type'] || '').downcase rows = row['rows'].to_i extra = (row['Extra'] || '').downcase key = row['key'] possible_keys = row['possible_keys'] alerts << "table scan on #{rows} rows" if (type.include?('all') && rows > config.table_scan_limit) alerts << "no index used" if (key.blank? && rows > config.table_scan_limit) alerts << "no index possible" if (possible_keys.blank? && rows > config.table_scan_limit) alerts << "dependent subquery" if select_type.include?('dependent') alerts << "uncacheable subquery" if select_type.include?('uncacheable') alerts << "full scan on null key" if extra.include?('full scan on null key') alerts << "uses temporary table for #{rows} rows" if extra.include?('using temporary') && rows > config.temporary_table_limit alerts << "uses filesort for #{rows} rows" if extra.include?('filesort') && rows > config.filesort_limit alerts << "examined #{rows} rows" if rows > config.examined_rows_limit end alerts end |