Module: PgQueryOptimizer::ClassMethods

Defined in:
lib/pg_query_optimizer.rb

Constant Summary collapse

DEFAULT_SETTINGS =
{
  max_parallel_workers_per_gather: 4,
  parallel_setup_cost: 1000,
  parallel_tuple_cost: 0.1,
  min_parallel_table_scan_size: '8MB',
  min_parallel_index_scan_size: '512kB'
}.freeze

Instance Method Summary collapse

Instance Method Details

#enable_parallel_executionObject



46
47
48
49
50
51
# File 'lib/pg_query_optimizer.rb', line 46

def enable_parallel_execution
  store_current_values
  DEFAULT_SETTINGS.each do |key, value|
    ActiveRecord::Base.connection.execute("SET #{key} = '#{value}'")
  end
end

#estore_previous_valuesObject



32
33
34
35
36
# File 'lib/pg_query_optimizer.rb', line 32

def estore_previous_values
  @previous_values.each do |key, value|
    ActiveRecord::Base.connection.execute("SET #{key} = '#{value}'")
  end
end

#pg_optimize(max_workers: 4) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/pg_query_optimizer.rb', line 57

def pg_optimize(max_workers: 4)
  verify_postgresql_adapter!
  if sufficient_resources?
    enable_parallel_execution
    yield
  else
    # If resources are insufficient, run the query without parallel execution
    yield
  end
ensure
  reset_parallel_execution 
end

#reset_parallel_executionObject



53
54
55
# File 'lib/pg_query_optimizer.rb', line 53

def reset_parallel_execution
  restore_previous_values
end

#store_current_valuesObject



22
23
24
25
26
27
28
29
30
# File 'lib/pg_query_optimizer.rb', line 22

def store_current_values
  @previous_values = {
    max_parallel_workers_per_gather: ActiveRecord::Base.connection.execute("SHOW max_parallel_workers_per_gather").first["max_parallel_workers_per_gather"],
    parallel_setup_cost: ActiveRecord::Base.connection.execute("SHOW parallel_setup_cost").first["parallel_setup_cost"],
    parallel_tuple_cost: ActiveRecord::Base.connection.execute("SHOW parallel_tuple_cost").first["parallel_tuple_cost"],
    min_parallel_table_scan_size: ActiveRecord::Base.connection.execute("SHOW min_parallel_table_scan_size").first["min_parallel_table_scan_size"],
    min_parallel_index_scan_size: ActiveRecord::Base.connection.execute("SHOW min_parallel_index_scan_size").first["min_parallel_index_scan_size"]
  }
end

#sufficient_resources?Boolean



38
39
40
41
42
43
44
# File 'lib/pg_query_optimizer.rb', line 38

def sufficient_resources?
  # Implement checks to ensure system has sufficient resources
  total_memory = `free -m | grep Mem: | awk '{print $2}'`.to_i
  required_memory = 1024 # required memory in MB

  total_memory >= required_memory
end

#verify_postgresql_adapter!Object



70
71
72
73
74
# File 'lib/pg_query_optimizer.rb', line 70

def verify_postgresql_adapter!
  unless ActiveRecord::Base.connection.adapter_name.downcase == 'postgresql'
    raise UnsupportedDatabaseError, "PgQueryOptimizer only supports PostgreSQL"
  end
end