Skip to content

Instantly share code, notes, and snippets.

@thefotios
Created January 18, 2022 22:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thefotios/fa00829c740555726f8120970f7151eb to your computer and use it in GitHub Desktop.
Save thefotios/fa00829c740555726f8120970f7151eb to your computer and use it in GitHub Desktop.
Format and visualize AR queries using https://explain.dalibo.com
class VisualizeQuery
# Takes an AR relation (query), runs explain, and then uploads it to
# https://explain.dalibo.com for better visualization
#
# The query is also nicely formatted before visualizing using https://github.com/darold/pgFormatter
# - This is run via `docker`
# - If the placeholders are sensitive (for instance emails in a 'where' clause)
# you can pass `anonymize: true` and they'll be replaced with random strings
method_object :query, [title: nil, anonymize: false]
def call
Faraday
.new(url: 'https://explain.dalibo.com', headers: {'Content-Type' => 'application/json'})
.post("/new", {
plan: plan,
title: title,
query: formatted,
}.compact.to_json)
.headers['location']
end
private
# This disables seq scan so that it forces the use of indices on smaller DBs
# to more accurately reflect production
TEMPLATE = <<~EOS
SET enable_seqscan = OFF;
EXPLAIN (ANALYZE, COSTS, VERBOSE, BUFFERS, FORMAT JSON)
%s
EOS
def formatted
@formatted ||= %x(echo "#{query.to_sql}" | docker run --rm -a stdin -a stdout -i darold.net/pgformatter #{anonymize ? "-a": ""} -)
end
def plan
@plan ||= ActiveRecord::Base.connection.execute(TEMPLATE % [query.to_sql])[0]['QUERY PLAN']
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment