在执行之前记录查询

时间:2009-03-06 12:59:09

标签: mysql ruby-on-rails database performance

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

3 个答案:

答案 0 :(得分:5)

我认为你有几个选择。第一个是真正看看你的development.log并查看导致它的行为。看看你要求运行的查询并尝试查明该特定查询。如果花费大量时间,这可能意味着你正在做一些事情,比如返回n + 1个查询,丢失索引或其他一些性能杀手。

你说开发日志只有完成的查询。你不能弄清楚下一个运行的查询是什么吗?

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

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

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

show processlist;

为了防止这样的事情再次发生,您还可能需要一些时间来查看来自New Relic(http://www.newrelic.com/)的RPM性能监视器。

我希望这有帮助!

答案 1 :(得分:2)

您可以通过

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

命令。

答案 2 :(得分:1)

如果您已对MySQL进行评估,请考虑SQL查询

SHOW PROCESSLIST

或者从命令行:

mysqladmin processlist

或者,最强大的方法是覆盖ActiveRecord :: Base连接实例的'execute'方法。本文介绍了一般方法:

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 <<