Class: Dexter::Indexer
- Inherits:
-
Object
- Object
- Dexter::Indexer
- Includes:
- Logging
- Defined in:
- lib/dexter/indexer.rb
Instance Method Summary collapse
-
#initialize(options) ⇒ Indexer
constructor
A new instance of Indexer.
- #process_queries(queries) ⇒ Object
- #process_stat_statements ⇒ Object
Methods included from Logging
Constructor Details
#initialize(options) ⇒ Indexer
Returns a new instance of Indexer.
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# File 'lib/dexter/indexer.rb', line 5 def initialize() @create = [:create] @log_level = [:log_level] @exclude_tables = [:exclude] @include_tables = Array([:include].split(",")) if [:include] @log_sql = [:log_sql] @log_explain = [:log_explain] @min_time = [:min_time] || 0 @min_calls = [:min_calls] || 0 @analyze = [:analyze] @options = create_extension unless extension_exists? execute("SET lock_timeout = '5s'") end |
Instance Method Details
#process_queries(queries) ⇒ Object
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 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 |
# File 'lib/dexter/indexer.rb', line 27 def process_queries(queries) # reset hypothetical indexes reset_hypothetical_indexes tables = Set.new(database_tables) if @include_tables include_set = Set.new(@include_tables) tables.keep_if { |t| include_set.include?(t) || include_set.include?(t.split(".")[-1]) } end if @exclude_tables.any? exclude_set = Set.new(@exclude_tables) tables.delete_if { |t| exclude_set.include?(t) || exclude_set.include?(t.split(".")[-1]) } end # map tables without schema to schema no_schema_tables = {} search_path_index = Hash[search_path.map.with_index.to_a] tables.group_by { |t| t.split(".")[-1] }.each do |group, t2| no_schema_tables[group] = t2.sort_by { |t| search_path_index[t.split(".")[0]] || 1000000 }[0] end # filter queries from other databases and system tables queries.each do |query| # add schema to table if needed query.tables = query.tables.map { |t| no_schema_tables[t] || t } # check for missing tables query.missing_tables = !query.tables.all? { |t| tables.include?(t) } end # set tables tables = Set.new(queries.reject(&:missing_tables).flat_map(&:tables)) # analyze tables if needed analyze_tables(tables) if tables.any? && (@analyze || @log_level == "debug2") # create hypothetical indexes and explain queries candidates = tables.any? ? create_hypothetical_indexes(queries.reject(&:missing_tables), tables) : {} # see if new indexes were used and meet bar new_indexes = determine_indexes(queries, candidates, tables) # display and create new indexes show_and_create_indexes(new_indexes, queries, tables) end |
#process_stat_statements ⇒ Object
21 22 23 24 25 |
# File 'lib/dexter/indexer.rb', line 21 def process_stat_statements queries = stat_statements.map { |q| Query.new(q) }.sort_by(&:fingerprint).group_by(&:fingerprint).map { |_, v| v.first } log "Processing #{queries.size} new query fingerprints" process_queries(queries) end |