我应该在MySQL中增加sort_buffer_size吗?

时间:2015-03-13 20:57:53

标签: mysql

我正在运行一个广泛查询MySQL数据库的站点。查询数据库服务器的某些页面加载速度非常慢,我很确定这是由于数据库服务器造成的。通过查看数据库服务器的使用情况,我可以看到iowait> 10秒,交换空间也被部分使用。打开慢查询日志后,我发现一个查询一直很慢。查询看起来像

select g.citing from g, c where g.cited=8992 and g.citing=c.id order by c.size desc limit 20;

典型查询时间约为10秒。 innodb_buffer_pool_size设置为24GB。我读了一些MySQL手册页,发现我可能需要调整sort_buffer_size参数,因为Sort_merge_passes状态变量非常高(大约310818)。 sort_buffer_size的当前值是2M,我不确定是否应该上升或下降,因为有些人说永远不会超过2M。 当前查询不利用索引。 " EXPLAIN"的结果声明给出了以下结果:

+----+-------------+-----------+--------+---------------+---------+---------+--------------------------------+------+---------------------------------+
| id | select_type | table     | type   | possible_keys | key     | key_len | ref                            | rows | Extra                           |
+----+-------------+-----------+--------+---------------+---------+---------+--------------------------------+------+---------------------------------+
|  1 | SIMPLE      | g         | ref    | citing,cited  | cited   | 8       | const                          |  306 | Using temporary; Using filesort |
|  1 | SIMPLE      | c         | eq_ref | PRIMARY,id    | PRIMARY | 8       | db1.g.citing                    |    1 |                 |
+----+-------------+-----------+--------+---------------+---------+---------+--------------------------------+------+---------------------------------+

我试图考虑一个更好的查询,它可以利用索引,但现在没有运气。谁能帮我吗?我很感激。

2 个答案:

答案 0 :(得分:1)

简而言之,没有。

如果你能避免它,那就不行了。

在增加任何类型的内存分配之前,请尝试寻找替代解决方案。通常这将是两件事中的一件(或两件):查询优化和索引。

在您的情况下,可以非常显着地优化查询。它目前正在做的是查询g 中的每一行乘以 c中的每一行,然后应用where子句,然后{{{} 1}},然后是order by

如果您使用联接,请执行以下操作:

limit

这样做是为了查询select g.citing from g inner join c on g.citing=c.id where g.cited=8992 order by c.size desc limit 20; 中的每一行,然后查询g中的每一行以查找匹配项,然后在两个表的交集处应用c子句 - 行数比以前少得多 - 其次是whereorder by

使用c.id上的主索引和g.citing和g.cited上的索引,你应该提高速度并进一步降低内存使用量。

答案 1 :(得分:0)

只有一个状态变量关心sort_buffer_size。 MySQL文档说:

Sort_merge_passes:排序算法必须执行的合并通过次数。如果此值很大,则应考虑增加sort_buffer_size系统变量的值。

请记住关于sort_buffer_size的一件事。

如果在SHOW GLOBAL STATUS输出中看到每秒有很多Sort_merge_passes,则可以考虑增加sort_buffer_size值以加快ORDER BY或GROUP BY操作,这些操作无法通过查询优化或改进的索引来改善

提高sort_buffer_size可以帮助查询GROUP BYORDER BY的同时,最好改进可改进的查询并添加索引可以由查询优化器使用。

问题仍然存在:如何检查Sort_merge_passes Sort_merge_passes

使用此代码,检查最近5分钟内发生了多少次Sort_merge_passes。它还会计算每小时的Sort_merge_passes。

SET @SleepTime = 300;
SELECT variable_value INTO @SMP1
FROM information_schema.global_status WHERE variable_name = 'Sort_merge_passes';
SELECT SLEEP(@SleepTime) INTO @x;
SELECT variable_value INTO @SMP2
FROM information_schema.global_status WHERE variable_name = 'Sort_merge_passes';
SET @SMP = @SMP2 - @SMP1;
SET @SMP_RATE = @SMP * 3600 / @SleepTime;
SELECT @SMP,@SMP_RATE;

如果您发现Sort_merge_passes和速率太高,请随时增加sort_buffer_size。假设您想提高到4M。您将运行以下代码:

mysql> SET GLOBAL sort_buffer_size = 1024 * 1024 * 4;

然后将其添加到my.cnf

[mysqld]
sort_buffer_size = 4M

您将定期运行代码以检查是否有其他时间Sort_merge_passes峰值。