您的第一步应该是找出数据库在运行缓慢时在做什么。使用 MySQL 最简单的方法是使用slow_query_log。一些合理的设置是:
log_slow_queries = /var/log/mysql/mysql-slow.log
long_query_time = 2
log-queries-not-using-indexes
启用此功能后,您将看到如下内容:
# User@Host: myuser[myuser] @ localhost [] # Query_time: 10.000347 Lock_time: 10.000094 Rows_sent: 2 Rows_examined: 4
SET timestamp=1341519484;
select * from (mytab) where (field=value);
一旦您确定了一个运行缓慢的查询,您可以再次手动运行相同的查询以找出发生了什么,但这一次以“解释”为前缀:
mysql> explain select * from mytab;
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
| 1 | SIMPLE | mytab | ALL | NULL | NULL | NULL | NULL | 189 | |
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
然后,您可以识别缺失索引、是否存在不必要的请求等。有关架构的一些信息会很有用。
如果您还安装了类似 sar 或atop(例如,通过编辑 /etc/init.d/atop 将间隔 arg 更改为“60”,然后运行 /etc/init.d/ 将采样率设置得足够低) atop restart) 您可以关联请求出现在 slow_query_log 中时服务器的行为,以确定是否存在任何其他系统争用问题。
Note that databases like MySQL (or, in fact, most applications which don't use O_DIRECT) will take advantages of IO buffering, meaning that once a particular block of data is accessed once, it'll remain in a buffer until the kernel needs to free up that memory space. This means that running the same query time and time again, if that query is particularly inefficient, may not give equal results each time.
If you post some more information about the particular query and the schema we could try to look at it a little more.