Class: Dbviewer::QueryAnalyzer
- Inherits:
-
Object
- Object
- Dbviewer::QueryAnalyzer
- Defined in:
- lib/dbviewer/query_analyzer.rb
Overview
QueryAnalyzer handles analysis of query patterns and statistics
Instance Attribute Summary collapse
-
#adapter_name ⇒ Object
readonly
Instance methods for query analysis.
-
#connection ⇒ Object
readonly
Instance methods for query analysis.
Class Method Summary collapse
-
.detect_potential_n_plus_1(queries) ⇒ Object
Detect potential N+1 query patterns.
-
.generate_stats(queries) ⇒ Object
Calculate statistics for a collection of queries.
-
.get_slowest_queries(queries, limit: 5) ⇒ Object
Get the slowest queries from the dataset.
Instance Method Summary collapse
-
#analyze_query(table_name, query_params) ⇒ Hash
Analyze a query and provide performance statistics and recommendations.
-
#has_index_on?(table_name, column_name) ⇒ Boolean
Check if a table has an index on a column.
-
#initialize(connection) ⇒ QueryAnalyzer
constructor
Initialize the analyzer for instance methods.
Constructor Details
#initialize(connection) ⇒ QueryAnalyzer
Initialize the analyzer for instance methods
22 23 24 25 |
# File 'lib/dbviewer/query_analyzer.rb', line 22 def initialize(connection) @connection = connection @adapter_name = connection.adapter_name.downcase end |
Instance Attribute Details
#adapter_name ⇒ Object (readonly)
Instance methods for query analysis
18 19 20 |
# File 'lib/dbviewer/query_analyzer.rb', line 18 def adapter_name @adapter_name end |
#connection ⇒ Object (readonly)
Instance methods for query analysis
18 19 20 |
# File 'lib/dbviewer/query_analyzer.rb', line 18 def connection @connection end |
Class Method Details
.detect_potential_n_plus_1(queries) ⇒ Object
Detect potential N+1 query patterns
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/dbviewer/query_analyzer.rb', line 63 def self.detect_potential_n_plus_1(queries) potential_issues = [] # Group queries by request_id queries.group_by { |q| q[:request_id] }.each do |request_id, request_queries| # Skip if there are too few queries to indicate a problem next if request_queries.size < 5 # Look for repeated patterns within this request analyze_request_patterns(request_id, request_queries, potential_issues) end # Sort by number of repetitions (most problematic first) potential_issues.sort_by { |issue| -issue[:count] } end |
.generate_stats(queries) ⇒ Object
Calculate statistics for a collection of queries
5 6 7 8 9 10 11 12 13 14 15 |
# File 'lib/dbviewer/query_analyzer.rb', line 5 def self.generate_stats(queries) { total_count: queries.size, total_duration_ms: queries.sum { |q| q[:duration_ms] }, avg_duration_ms: calculate_average_duration(queries), max_duration_ms: queries.map { |q| q[:duration_ms] }.max || 0, tables_queried: extract_queried_tables(queries), potential_n_plus_1: detect_potential_n_plus_1(queries), slowest_queries: get_slowest_queries(queries) }.merge(calculate_request_stats(queries)) end |
.get_slowest_queries(queries, limit: 5) ⇒ Object
Get the slowest queries from the dataset
80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/dbviewer/query_analyzer.rb', line 80 def self.get_slowest_queries(queries, limit: 5) # Return top N slowest queries with relevant info queries.sort_by { |q| -q[:duration_ms] } .first(limit) .map do |q| { sql: q[:sql], duration_ms: q[:duration_ms], timestamp: q[:timestamp], request_id: q[:request_id], name: q[:name] } end end |
Instance Method Details
#analyze_query(table_name, query_params) ⇒ Hash
Analyze a query and provide performance statistics and recommendations
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/dbviewer/query_analyzer.rb', line 43 def analyze_query(table_name, query_params) results = { table: table_name, filters: query_params.column_filters.keys, analysis: [], recommendations: [] } # Check created_at filter performance if query_params.column_filters["created_at"].present? (table_name, "created_at", results) end # Add general performance recommendations based on database type add_database_specific_recommendations(results) results end |
#has_index_on?(table_name, column_name) ⇒ Boolean
Check if a table has an index on a column
31 32 33 34 35 36 37 |
# File 'lib/dbviewer/query_analyzer.rb', line 31 def has_index_on?(table_name, column_name) indexes = connection.indexes(table_name) indexes.any? do |index| index.columns.include?(column_name) || (index.columns.length == 1 && index.columns[0] == column_name) end end |