【发布时间】:2013-10-16 13:04:54
【问题描述】:
我有一个较大但很窄的 InnoDB 表,其中有大约 9m 条记录。在桌子上做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(*) 性能的方法是什么?
【问题讨论】:
-
更改为 MyISAM 可以创造奇迹 - 在 PHPMyAdmin 中只需单击一次。)
-
@davidkonrad 执行外键和使用事务也需要花费。
-
@Jim,现在我明白了,我认为您的意思是事务或外键对于 MyISAM 是强制性的,我认为不是。被误解的“强制执行”
-
@davidkonrad:是的,但不是问的问题:/
-
channel_id上的索引与以该列开头的索引是多余的;放弃前者。