COUNT(id) 查询花费的时间太长,哪些性能增强可能会有所帮助?

Posted

技术标签:

【中文标题】COUNT(id) 查询花费的时间太长,哪些性能增强可能会有所帮助?【英文标题】:COUNT(id) query is taking too long, what performance enhancements might help? 【发布时间】:2011-06-24 23:08:40 【问题描述】:

我有一个查询超时问题。当我做了一个:

SELECT COUNT(id) AS rowCount FROM infoTable;

在我的程序中,我的 JDBC 调用在 2.5 分钟后超时。

我没有太多的数据库管理专业知识,但我目前的任务是支持旧数据库。在这个mysql数据库中,有一个InnoDB表:

+-------+------------+------+-----+---------+----------------+
| Field | Type       | Null | Key | Default | Extra          |
+-------+------------+------+-----+---------+----------------+
| id    | bigint(20) | NO   | PRI | NULL    | auto_increment | 
| info  | longtext   | NO   |     |         |                | 
+-------+------------+------+-----+---------+----------------+

它当前的高 id 为 5,192,540,这是表中的大致行数。有些信息文本超过 1M,有些非常小。每天添加大约 3000 行。机器有大量可用磁盘空间,但没有很多额外内存。行被读取并偶尔被修改,但很少被删除,尽管我希望清除一些几乎已经过时的旧数据。

我在一个较小的测试数据库上手动尝试了相同的查询,该数据库有 1,492,669 行,安装在磁盘空间较小的类似机器上,耗时 9.19 秒。

我在一个更小的测试数据库上手动尝试了相同的查询,该数据库有 98,629 行,耗时 3.85 秒。然后我在 id 中添加了一个索引:

create index infoTable_idx on infoTable(id);

随后的 COUNT 耗时 4.11 秒,因此在这种情况下,添加索引似乎没有帮助。 (只是为了好玩,我在上述中型数据库上做了同样的事情,访问时间从 9.2 秒增加到 9.3 秒。)

知道这样的查询需要多长时间吗?在此查询期间锁定了什么?如果有人在我的程序选择时添加数据会怎样?

感谢您的任何建议, 伊莱恩

【问题讨论】:

您不需要在 id 字段上创建索引,因为您不是根据 id 搜索行。而且它是主键,所以它应该已经被索引了。是否有任何应用程序/系统与数据库在同一台服务器上运行?在我看来这是一个磁盘问题:p @Zaq,@Ilane,正确 - 主键上完全不需要索引.. 将 bigint 设置为 10 而不是 20 可能会加快速度,因为它会使列和表变小。据我了解,即使您没有 WHERE 子句,而不仅仅是 id 列,InnoDb Count 仍将遍历整个表。 mysqlperformanceblog.com/2006/12/01/count-for-innodb-tables 磁盘实际上是1.6T的镜像RAID。有一个 JBoss 在同一个系统上运行,但使用另一个磁盘。 【参考方案1】:

你可以尝试执行下面的解释语句,可能会快一点:

mysql> EXPLAIN SELECT id FROM table;

这可能会或可能不会产生更快的结果,请查找 rows 字段。

【讨论】:

以上是关于COUNT(id) 查询花费的时间太长,哪些性能增强可能会有所帮助?的主要内容,如果未能解决你的问题,请参考以下文章

查询在简单选择上花费的时间太长

Oracle SQL 查询在 JdbcTemplate 和 SimpleJdbcTemplate 中花费的时间太长

Mysql 性能:哪个查询会花费更多时间?

如何优化这个 sql 查询(内连接)

查询花费了太多时间与恼人的性能[关闭]

MySQL count(*) 性能优化