Class: Mxrb::Oql::WorkloadAnalyzer

Inherits:
Object
  • Object
show all
Defined in:
lib/mxrb/oql/workload_analyzer.rb

Overview

Interprets cumulative PostgreSQL statistics without pretending that one threshold is universally optimal. Findings retain the measured values so callers can rank them against their own latency and throughput budgets.

Constant Summary collapse

TOTAL_TIME_MS =

rubocop:disable Metrics/ClassLength

1_000.0
MEAN_TIME_MS =
100.0
MIN_BUFFER_BLOCKS =
100
MIN_CACHE_HIT_RATIO =
0.90
HIGH_ROWS_PER_CALL =
10_000
LARGE_UNUSED_INDEX_BYTES =
1_048_576
HEAVY_SEQ_ROWS =
100_000
DEFAULT_THRESHOLDS =
{
  total_time_ms: TOTAL_TIME_MS, mean_time_ms: MEAN_TIME_MS,
  min_buffer_blocks: MIN_BUFFER_BLOCKS, min_cache_hit_ratio: MIN_CACHE_HIT_RATIO,
  high_rows_per_call: HIGH_ROWS_PER_CALL,
  large_unused_index_bytes: LARGE_UNUSED_INDEX_BYTES, heavy_seq_rows: HEAVY_SEQ_ROWS
}.freeze

Instance Method Summary collapse

Constructor Details

#initialize(**thresholds) ⇒ WorkloadAnalyzer

Returns a new instance of WorkloadAnalyzer.

Raises:

  • (ArgumentError)


34
35
36
37
38
39
# File 'lib/mxrb/oql/workload_analyzer.rb', line 34

def initialize(**thresholds)
  unknown = thresholds.keys - DEFAULT_THRESHOLDS.keys
  raise ArgumentError, "unknown workload thresholds: #{unknown.join(', ')}" unless unknown.empty?

  @thresholds = DEFAULT_THRESHOLDS.merge(thresholds).freeze
end

Instance Method Details

#analyze(query_rows:, table_rows:, index_rows:) ⇒ Object



41
42
43
44
45
46
47
48
49
# File 'lib/mxrb/oql/workload_analyzer.rb', line 41

def analyze(query_rows:, table_rows:, index_rows:)
  queries = query_rows.map { query_entry(_1) }.freeze
  findings = [
    *queries.flat_map { query_findings(_1) },
    *table_rows.filter_map { table_finding(_1) },
    *index_rows.filter_map { index_finding(_1) }
  ].freeze
  WorkloadReport.new(:postgresql, queries, table_rows.freeze, index_rows.freeze, findings)
end