mysql - 计算执行的查询数

我想测试一段代码是否执行尽可能少的 SQL 查询。

ActiveRecord::TestCase 似乎有自己的 assert_queries 方法,可以做到这一点。但由于我没有修补 ActiveRecord,它对我来说没什么用。

RSpec 或 ActiveRecord 是否提供任何官方、公开的方法来计算代码块中执行的 SQL 查询的数量?

最佳答案

我认为您通过提及 assert_queries 回答了您自己的问题,但这里是:

我建议您查看 assert_queries 背后的代码,并使用它来构建您自己的方法,您可以使用该方法对查询进行计数。这里涉及的主要魔法是这一行:

ActiveSupport::Notifications.subscribe('sql.active_record', SQLCounter.new)

今天早上我做了一点小改动,并删除了 ActiveRecord 中执行查询计数的部分,并提出了这个:

module ActiveRecord
  class QueryCounter
    cattr_accessor :query_count do
      0
    end

    IGNORED_SQL = [/^PRAGMA (?!(table_info))/, /^SELECT currval/, /^SELECT CAST/, /^SELECT @@IDENTITY/, /^SELECT @@ROWCOUNT/, /^SAVEPOINT/, /^ROLLBACK TO SAVEPOINT/, /^RELEASE SAVEPOINT/, /^SHOW max_identifier_length/]

    def call(name, start, finish, message_id, values)
      # FIXME: this seems bad. we should probably have a better way to indicate
      # the query was cached
      unless 'CACHE' == values[:name]
        self.class.query_count += 1 unless IGNORED_SQL.any? { |r| values[:sql] =~ r }
      end
    end
  end
end

ActiveSupport::Notifications.subscribe('sql.active_record', ActiveRecord::QueryCounter.new)

module ActiveRecord
  class Base
    def self.count_queries(&block)
      ActiveRecord::QueryCounter.query_count = 0
      yield
      ActiveRecord::QueryCounter.query_count
    end
  end
end

您将能够在任何地方引用 ActiveRecord::Base.count_queries 方法。向它传递一个运行查询的 block ,它将返回已执行的查询数:

ActiveRecord::Base.count_queries do
  Ticket.first
end

为我返回“1”。要完成这项工作:将其放在 lib/active_record/query_counter.rb 的文件中,并在 config/application.rb 文件中要求它,如下所示:

require 'active_record/query_counter'

你好!


可能需要一点解释。当我们调用此行时:

    ActiveSupport::Notifications.subscribe('sql.active_record', ActiveRecord::QueryCounter.new)

我们连接到 Rails 3 的小通知框架。它是 Rails 最新主要版本的一个 Shiny 的小补充,没有人真正知道。它允许我们使用 subscribe 方法订阅 Rails 中的事件通知。我们将要订阅的事件作为第一个参数传递,然后将响应 call 的任何对象作为第二个参数传递。

在这种情况下,当执行查询时,我们的小查询计数器将尽职尽责地增加 ActiveRecord::QueryCounter.query_count 变量,但仅限于真正的查询。

无论如何,这很有趣。希望对你有用。

https://stackoverflow.com/questions/5490411/

相关文章:

php - 从字段不匹配条件的表中选择

mysql - 最好的 MySQL 性能调优工具?

mysql - 列计数与第 1 行的值计数不匹配

php - 如何使用 Laravel 4 Eloquent 连接列?

php - DateTime 类的对象无法转换为字符串

mysql - 如何在mysql中将字符串转换为 float ?

php - PDO fetchAll 将键值对分组到 assoc 数组中

mysql - 如何在 SQL 查询中对 LEFT JOIN 的顺序进行排序?

mysql - 设计用户角色和权限系统的最佳实践?

php - MySQL 删除多列