mysql - 如何使用索引优化 InnoDB 上的 COUNT(*) 性能

标签 mysql innodb

我有一个较大但狭窄的 InnoDB 表,其中有约 9m 条记录。在 table 上执行 count(*)count(id) 非常慢(6 秒以上):

DROP TABLE IF EXISTS `perf2`;

CREATE TABLE `perf2` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `channel_id` int(11) DEFAULT NULL,
  `timestamp` bigint(20) NOT NULL,
  `value` double NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `ts_uniq` (`channel_id`,`timestamp`),
  KEY `IDX_CHANNEL_ID` (`channel_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

RESET QUERY CACHE;
SELECT COUNT(*) FROM perf2;

虽然该语句运行得不太频繁,但最好对其进行优化。根据http://www.cloudspace.com/blog/2009/08/06/fast-mysql-innodb-count-really-fast/这应该可以通过强制 InnoDB 使用索引来实现:

SELECT COUNT(id) FROM perf2 USE INDEX (PRIMARY);

解释计划似乎不错:

id  select_type table   type    possible_keys   key     key_len ref     rows    Extra
1   SIMPLE      perf2   index   NULL            PRIMARY 4       NULL    8906459 Using index

不幸的是,该语句和以前一样慢。根据"SELECT COUNT(*)" is slow, even with where clause我也尝试过优化表格,但没有成功。

有什么方法可以优化 InnoDB 上的 COUNT(*) 性能?

最佳答案

从 MySQL 5.1.6 开始,您可以使用 Event Scheduler并定期将计数插入统计表。

首先创建一个表来保存计数:

CREATE TABLE stats (
`key` varchar(50) NOT NULL PRIMARY KEY,
`value` varchar(100) NOT NULL);

然后创建一个事件来更新表:

CREATE EVENT update_stats
ON SCHEDULE
  EVERY 5 MINUTE
DO
  INSERT INTO stats (`key`, `value`)
  VALUES ('data_count', (select count(id) from data))
  ON DUPLICATE KEY UPDATE value=VALUES(value);

它并不完美,但它提供了一个独立的解决方案(无 cronjob 或队列),可以轻松定制以根据所需的计数新鲜度运行。

关于mysql - 如何使用索引优化 InnoDB 上的 COUNT(*) 性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54324458/

相关文章:

java - 某些服务器上的 MySQL 数据截断错误

php - 从sql语句中删除

java - 使用文档监听器实时显示搜索结果?

mysql - 更新具有索引的列值的影响?

mysql - 将表从 MyISAM 更改为 InnoDB 会使系统变慢

MySQL外键约束、级联删除

mysql - 查询时出现错误 'Unknown table engine ' InnoDB''。重启mysql后

MySQL 对一个表中选定的行进行计数以更新另一表中的值

php - 插入数据库表时发出通知声音

mysql - 在 InnoDB 上重建索引