具有低内存的Mysql性能

时间:2016-04-05 08:21:11

标签: php mysql performance

我的服务器上有一个严重的mysql性能问题。我有一个非常大的表,不是特别是行数(~90万行),而是列数(~90列)和大量索引(~30个索引)(它是Innodb表)。

当我在一段时间内没有进行任何查询后从表中执行计数(*)时,查询可能需要花费很长时间,这是show processlist的结果:

| Command | Time | State        | Info                                                                                      |
| Query   | 430  | Sending data | SELECT COUNT(*) FROM CATALOG where PUBLISH = 1 and (Exclusions = 2 or Exclusions is null) |

差不多10分钟做一个计数(*),当我在那之后尝试没有缓存时:

mysql> SELECT SQL_NO_CACHE COUNT(*) FROM CATALOG where PUBLISH = 1 and (Exclusions = 2 or Exclusions is null);
+----------+
| COUNT(*) |
+----------+
|   900872 |
+----------+
1 row in set (0.66 sec)

或者使用缓存:

mysql> SELECT COUNT(*) FROM CATALOG where PUBLISH = 1 and (Exclusions = 2 or Exclusions is null);
+----------+
| COUNT(*) |
+----------+
|   900872 |
+----------+
1 row in set (0.00 sec)

mysql可以在这张桌子上为10mn做什么?也许是缺乏记忆?服务器上的交换非常高......

编辑:这是查询的解释

mysql> explain SELECT COUNT(*) FROM CATALOG where PUBLISH = 1 and (Exclusions = 2 or Exclusions is null);
+----+-------------+---------+------+---------------+------+---------+------+--------+-------------+
| id | select_type | table   | type | possible_keys | key  | key_len | ref  | rows   | Extra       |
+----+-------------+---------+------+---------------+------+---------+------+--------+-------------+
|  1 | SIMPLE      | CATALOG | ALL  | NULL          | NULL | NULL    | NULL | 905537 | Using where |
+----+-------------+---------+------+---------------+------+---------+------+--------+-------------+
1 row in set (0.14 sec)

1 个答案:

答案 0 :(得分:0)

请提供SHOW CREATE TABLESHOW TABLE STATUS LIKE 'CATALOG';

30个索引很多。

INDEX(PUBLISH, Exclusions)

将是查询的最佳索引。 EXPLAIN会说Using index而不是Using where

基于EXPLAIN,它进行了表格扫描; 0.66秒也不错。缓存版本无关紧要;它在"查询缓存中找到了查询"并且没有做任何实际工作就返回了结果。 InnoDB有" buffer_pool",它似乎包含整个表,因此0.66秒,显然没有任何I / O.

innodb_buffer_pool_size的价值是什么?

" mysql可以在这张桌子上为10mn做什么?" - 你在问什么;什么是' mn'? MySQL几乎可以处理任何大小的表。随着桌子变大,表扫描需要更长的时间。一旦表变得大于buffer_pool,表扫描将变为I / O绑定,并且此查询将显着减慢。但它(最终)将完成。 (我不会在你的输出中的任何地方看到" 10 分钟")

如果你将MySQL配置为使用太多内存,那么它就会变换,那么性能将变得非常,真实,糟糕。单行规则:buffer_pool应该是大约70%或可用RAM。较小的效率较低;更大的威胁要交换。

这张桌子是什么引擎?如果它是MyISAM,那么其他一些操作可能会锁定表。总的来说,InnoDB更好。

COUNT(*)是正常的说法; COUNT(1)以同样的努力为您提供相同的答案。 COUNT(col)会增加col作为NULL检查的负担。

除非您通过ALTEROPTIMIZE提出索引,否则MySQL不会重建索引。索引以递增方式维护。除了极少数例外,它们总是处于接近最佳格式。

在不知道导致问题的原因的情况下,将内存加倍可能不符合成本效益。