【问题标题】:Log query before executing it在执行之前记录查询
【发布时间】:2010-10-11 18:03:01
【问题描述】:

我遇到了一个问题,我运行了一些查询,mysqld 进程开始使用 100% 的 CPU 功率,但没有结束。我想查明这个查询。问题是 log/development.log 只包含已完成的查询。有什么想法吗?

【问题讨论】:

    标签: mysql ruby-on-rails database performance


    【解决方案1】:

    我认为您对此有几个选择。首先是真正查看您的 development.log 并查看导致它的操作。查看您要求 rails 运行的查询并尝试查明该特定查询。如果花费大量时间,则可能意味着您正在执行诸如返回 n+1 个查询、缺少索引或其他一些性能杀手之类的事情。

    您说开发日志中只有已完成的查询。你不知道下一个要运行的查询是什么吗?

    您的其他选项涉及使用日志启动 mysqld(我认为其中一些名称已更改):

    mysqld --log[=file_name] --log-slow-queries[=file_name]
    

    使用 mysql 中的 processlist 显示当前语句列表:

    show processlist;
    

    为防止此类事情再次发生,您还可以花一些时间查看 Rails 性能监视器,例如 New Relic (http://www.newrelic.com/) 的 RPM。

    我希望这会有所帮助!

    【讨论】:

    • 同意 - 通过查看开发日志,您可以看到调用了哪个控制器方法,它应该告诉您要查看哪个模型。此时,您可以在必要时添加日志记录,以告诉您将要运行哪个查询。
    【解决方案2】:

    您可以通过

    查看正在运行/未完成的语句
    show processlist;
    

    命令。

    【讨论】:

      【解决方案3】:

      如果您对 MySQL 有评估,请考虑 SQL 查询

      SHOW PROCESSLIST
      

      或者从命令行:

      mysqladmin processlist
      

      另外,最强大的方法是覆盖 ActiveRecord::Base 连接实例的“执行”方法。本文展示了一般方法:

      http://www.misuse.org/science/2006/12/12/sql-logging-in-rails/

      你把这段代码放到application.rb中:

      # define SQL_LOG_FILE, SQL_LOG_MAX_LINES
      
      connection = ActiveRecord::Base.connection
      class << connection
          alias :original_exec :execute
          def execute(sql, *name)
              # try to log sql command but ignore any errors that occur in this block
              # we log before executing, in case the execution raises an error
              begin
                  lines = if File::exists?(SQL_LOG_FILE) then IO::readlines(SQL_LOG_FILE) else [] end
                  log = File.new(SQL_LOG_FILE, "w+")
                  # keep the log to specified max lines
                  if lines.length > SQL_LOG_MAX_LINES
                      lines.slice!(0..(lines.length-SQL_LOG_MAX_LINES))
                  end
                  lines << Time.now.strftime("%x %I:%M:%S %p")+": "+sql+"n"
                  log.write(lines)
                  log.close
                  $sql_log = sql
              rescue Exception => e
                  ;
              end
              # execute original statement
              original_exec(sql, *name)
          end # def execute
      end # class <<
      

      【讨论】:

        猜你喜欢
        • 2023-03-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-09-08
        • 2017-05-10
        相关资源
        最近更新 更多