PERF: remove SQL notifiers for every SQL execution

PERF: remove SQL notifiers for every SQL execution

Benchmarking:

Benchmark.ips do |b|
  b.report("simple") do
    User.first
  end
end

ActiveSupport::Notifications.notifier.listeners_for("sql.active_record").clear

Benchmark.ips do |b|
  b.report("simple") do
    User.first
  end
end

sam@arch discourse % RAILS_ENV=production ruby script/micro_bench.rb

Before

Calculating -------------------------------------
              simple      3.289k (± 4.4%) i/s -     16.575k in   5.049771s
After

Calculating -------------------------------------
              simple      3.491k (± 3.6%) i/s -     17.442k in   5.002226s
diff --git a/config/initializers/300-perf.rb b/config/initializers/300-perf.rb
new file mode 100644
index 0000000..3186698
--- /dev/null
+++ b/config/initializers/300-perf.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+if Rails.env == "production"
+  # This event happens quite a lot and fans out to ExplainSubscriber
+  # and Logger, this cuts out 2 method calls that every time we run SQL
+  #
+  # In production we do not care about Explain or Logging SQL statements
+  # at this level
+  #
+  # Micro bench shows for `User.first` this takes us from 3.3k/s to 3.5k/s
+  ActiveSupport::Notifications.notifier.unsubscribe("sql.active_record")
+end

GitHub sha: 88249932

3 Likes

Note, in the Discourse case this is very relevant in production. A lot of SQL runs in MiniSql, this is not measured by Rails, so at the request level to break down PG vs App we need to call different stuff.

See:

This is the number we care about … sql.active_record is only a subset.

1 Like