【发布时间】:2016-04-05 08:21:10
【问题描述】:
我的服务器上的 mysql 存在严重的性能问题。我有一个很大的表,不是特别是行数(~900 000 行),而是更多的列数(~90 列)和很多索引(~30 个索引)(这是一个 Innodb 表)。
当我在一段时间内没有进行任何查询后从表中执行计数(*)时,查询可能需要很长时间,这是显示进程列表的结果:
| Command | Time | State | Info |
| Query | 430 | Sending data | SELECT COUNT(*) FROM CATALOG where PUBLISH = 1 and (Exclusions = 2 or Exclusions is null) |
几乎 1000 万个计数(*),然后当我在没有缓存的情况下尝试它时:
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 可以在这张表上为 1000 万做什么?也许是内存不足?服务器上的交换非常高......
编辑:这里是查询的解释
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)
【问题讨论】:
-
count(*) 使用每一列。如果你使用 COUNT(1) 怎么办?
-
^ 是的,具体一点,也可能您的索引不适合您的查询。因此,它不再使用索引,而是恢复为全表扫描。
-
您是否对计数查询进行了解释,以查看它可能使用的 30 个索引中的哪个(如果有)?
-
没有使用索引,可能查询不是很优化但它没有解释为什么有时它花费1000万来做它,而它花费0.66s来做它没有缓存。我添加了解释。
-
我想知道mysql是否没有重新计算所有表索引,我真的不知道索引是如何工作的,我不知道是否有可能。但它可以解释为什么要花费 1000 万,在这样的表上创建 30 个索引应该花费这么多时间。
标签: php mysql performance