Class: Dbviewer::Query::Analyzer

Inherits:
Object
  • Object
show all
Defined in:
lib/dbviewer/query/analyzer.rb

Overview

Analyzer handles analysis of query patterns and statistics

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(connection) ⇒ Analyzer

Initialize the analyzer for instance methods

Parameters:

  • connection (ActiveRecord::ConnectionAdapters::AbstractAdapter)

    Database connection



23
24
25
26
# File 'lib/dbviewer/query/analyzer.rb', line 23

def initialize(connection)
  @connection = connection
  @adapter_name = connection.adapter_name.downcase
end

Instance Attribute Details

#adapter_nameObject (readonly)

Instance methods for query analysis



19
20
21
# File 'lib/dbviewer/query/analyzer.rb', line 19

def adapter_name
  @adapter_name
end

#connectionObject (readonly)

Instance methods for query analysis



19
20
21
# File 'lib/dbviewer/query/analyzer.rb', line 19

def connection
  @connection
end

Class Method Details

.generate_stats(queries) ⇒ Object

Calculate statistics for a collection of queries



6
7
8
9
10
11
12
13
14
15
16
# File 'lib/dbviewer/query/analyzer.rb', line 6

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

Instance Method Details

#analyze_query(table_name, query_params) ⇒ Hash

Analyze a query and provide performance statistics and recommendations

Parameters:

Returns:

  • (Hash)

    Analysis results with statistics and recommendations



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/dbviewer/query/analyzer.rb', line 44

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.key?("created_at")
    analyze_timestamp_query(table_name, "created_at", results)
  end

  # Check updated_at filter performance
  if query_params.column_filters.key?("updated_at")
    analyze_timestamp_query(table_name, "updated_at", results)
  end

  # Check other filters for potential indexes
  query_params.column_filters.each do |column_name, _value|
    next if [ "created_at", "updated_at" ].include?(column_name)

    unless has_index_on?(table_name, column_name)
      results[:recommendations] << {
        type: "missing_index",
        message: "Consider adding an index on '#{column_name}' for faster filtering",
        sql: index_creation_sql(table_name, column_name)
      }
    end
  end

  # Add database-specific recommendations
  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

Parameters:

  • table_name (String)

    Name of the table

  • column_name (String)

    Name of the column

Returns:

  • (Boolean)

    True if column has an index, false otherwise



32
33
34
35
36
37
38
# File 'lib/dbviewer/query/analyzer.rb', line 32

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