lib/dexter/indexer.rb in pgdexter-0.3.3 vs lib/dexter/indexer.rb in pgdexter-0.3.4
- old
+ new
@@ -23,10 +23,27 @@
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
+ def stat_activity
+ execute <<-SQL
+ SELECT
+ pid || ':' || COALESCE(query_start, xact_start) AS id,
+ query,
+ EXTRACT(EPOCH FROM NOW() - COALESCE(query_start, xact_start)) * 1000.0 AS duration_ms
+ FROM
+ pg_stat_activity
+ WHERE
+ datname = current_database()
+ AND state = 'active'
+ AND pid != pg_backend_pid()
+ ORDER BY
+ 1
+ SQL
+ end
+
def process_queries(queries)
# reset hypothetical indexes
reset_hypothetical_indexes
tables = Set.new(database_tables + materialized_views)
@@ -164,11 +181,11 @@
query.plans << plan(query.statement)
if @log_explain
# Pass format to prevent ANALYZE
puts execute("EXPLAIN (FORMAT TEXT) #{safe_statement(query.statement)}").map { |r| r["QUERY PLAN"] }.join("\n")
end
- rescue PG::Error => e
+ rescue PG::Error, JSON::NestingError => e
if @log_explain
log e.message
end
end
puts if @log_explain
@@ -477,18 +494,21 @@
new_indexes
end
def conn
@conn ||= begin
+ # set connect timeout if none set
+ ENV["PGCONNECT_TIMEOUT"] ||= "2"
+
if @options[:dbname] =~ /\Apostgres(ql)?:\/\//
config = @options[:dbname]
else
config = {
host: @options[:host],
port: @options[:port],
dbname: @options[:dbname],
- user: @options[:user]
+ user: @options[:username]
}.reject { |_, value| value.to_s.empty? }
config = config[:dbname] if config.keys == [:dbname] && config[:dbname].include?("=")
end
PG::Connection.new(config)
end
@@ -509,10 +529,10 @@
conn.exec_params(query, []).to_a
end
def plan(query)
# strip semi-colons as another measure of defense
- JSON.parse(execute("EXPLAIN (FORMAT JSON) #{safe_statement(query)}").first["QUERY PLAN"]).first["Plan"]
+ JSON.parse(execute("EXPLAIN (FORMAT JSON) #{safe_statement(query)}").first["QUERY PLAN"], max_nesting: 1000).first["Plan"]
end
# TODO for multicolumn indexes, use ordering
def create_hypothetical_indexes_helper(columns_by_table, n, candidates)
columns_by_table.each do |table, cols|