识别慢速 Rails 查询:使用 sqlcommenter
在一个大型的 Rails 应用中,追踪导致慢查询的具体来源可能会很棘手。
解决这一问题的方案正在不断改善。起初,我们使用了 Marginalia 这个 gem,它能够为所有查询添加注释。通过查看日志,你可以知道查询来自哪个控制器或任务。 从 Rails 7 开始,Marginalia 已成为 Rails 的内置功能,不需要安装额外的 gem。这是一个很大的改进,但我们仍然可以进一步提升 Rails 查询注释的功能。
Rails + sqlcommenter
Sqlcommenter 是由 Google 创建的一种查询注释格式,已被许多工具和语言广泛采用。相比 Rails 当前默认的注释格式,它更容易被机器读取。 Rails 默认格式:
SELECT * FROM `users` ORDER BY `users`.`id` DESC LIMIT 1 /*application:Api,controller:users,action:show*/
sqlcommenter 格式:
SELECT * FROM `users` ORDER BY `users`.`id` DESC LIMIT 1 /*application='Api',controller='users',action='show'*/
虽然只是一个微小的改动,但这种格式让查询注释变得更易于机器解析,并在日志记录和性能监控工具中具有更大的价值。
在 Rails 7 中启用 sqlcommenter
为了方便在 Rails 中使用 sqlcommenter,我们创建了一个专用于 Rails 7 的 gem,以支持 sqlcommenter。 要尝试使用它,请在你的 Gemfile 中添加以下内容:
gem "activerecord-sql_commenter", require: "active_record/sql_commenter"
然后,在你的 Rails config/application.rb
文件中启用查询日志标签:
# config/application.rb config.active_record.query_log_tags_enabled = true config.active_record.query_log_tags = [:application, :controller, :action, :job] config.active_record.cache_query_log_tags = true
你可以在 Rails 查询日志文档 中了解这些配置选项的详细信息。
测试设置
完成配置后,你可以打开 Rails 控制台运行查询以测试效果:
$ rails console [1] pry(main)> User.first
你应该能在对应的 sqlcommenter 格式中看到应用的名称:
User Load (0.6ms) SELECT `user`.* FROM `user` ORDER BY `user`.`id` ASC LIMIT 1 /*application='ApiBb'*/
使用 annotate 方法
如果默认的查询日志标签不足以提供足够信息,Rails 7 还添加了一个名为 annotate
的方法,可让你针对查询添加自定义注释。 例如,以下查询会在注释中添加 source='user_metrics_runner'
:
[3] pry(main)> User.where(name: "iheanyi").annotate("source='user_metrics_runner'")
生成的 SQL 查询如下:
User Load (0.5ms) SELECT `user`.* FROM `user` WHERE `user`.`name` = 'iheanyi' /*source='user_metrics_runner'*/
在默认查询日志标签不足的情况下,annotate
方法非常有用。
与 PlanetScale Query Insights 一起使用
PlanetScale Query Insights 是我们提供的一种内置查询调试和分析工具,它与 sqlcommenter 兼容。任何运行时间超过 1 秒的查询都会被记录,并添加你在 sqlcommenter 中设置的标签值。 例如,以下是我们自己应用中的一个慢查询:
SELECT schema_snapshot.* FROM schema_snapshot WHERE schema_snapshot.ready = true AND created_at > :created_at AND schema_snapshot.deleted_at IS NULL ORDER BY schema_snapshot.id ASC LIMIT 10000 /*application='ApiBb',job='ScheduleSnapshotJob'*/
通过 Insights 和查询上的标签,我们能够快速定位该查询的来源,并立即着手解决相关问题。 PlanetScale Insights 仪表板中慢查询的标签示例 通过注册一个 PlanetScale 账户并导航至仪表板中的 “Insights”,可以立即试用 Query Insights。
关注公众号:程序新视界,一个让你软实力、硬技术同步提升的平台
除非注明,否则均为程序新视界原创文章,转载必须以链接形式标明本文链接
本文链接:http://www.choupangxia.com/2025/09/07/rails-sqlcommenter/