在mini_prof中加入query cache的统计
(其实用bullet也可以,不过顺便了解下mini_prof的运作吧)
在Gemfile加入mini_prof后,跟踪一下查询数据库时它是如何记录耗时和调用栈的
binding.trace_tree(htmp: 'mini_porfiler'){ Member.limit(1).to_a }
得调用栈如下:
在其中搜索mini,得:

找到这个被重写的async_exec,发现它是使用record_sql方法收集sql及耗时
def async_exec(*args, &blk)
return async_exec_without_profiling(*args, &blk) unless SqlPatches.should_measure?
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
result = exec_without_profiling(*args, &blk)
elapsed_time = SqlPatches.elapsed_time(start)
record = ::Rack::MiniProfiler.record_sql(args[0], elapsed_time)
result.instance_variable_set("@miniprofiler_sql_id", record) if result
result
end
于是,我们也可以利用这个方法来收集query cache出现的地方,而因为query cache不会发出sql,不能通过重写adapter的xx_exec来拦截,但它会输出日志,所以对该输出进行拦截即可
module QueryCacheProfiler
class Railtie < ::Rails::Railtie
initializer "rack_mini_profiler.query_cache" do |app|
::ActiveSupport::Notifications.subscribe('sql.active_record') do |*args|
opt = args[-1]
next if opt[:name] != "CACHE"
duration = 1000.0 * (args[2] - args[1])
::Rack::MiniProfiler.record_sql("(CACHE) #{opt[:sql]}", duration)
end
end
end
end
甚至可以包装成一个gem来使用,这样mini_prof的结果就会带上query cache的统计:https://github.com/turnon/query_cache_profiler