我有一个较大的 InnoDB 表(大约 800MB),我想计算行数。我知道SELECT COUNT(*)
InnoDB 存在问题,但我见过的解决方案之一是创建二级索引,这比咀嚼要快得多PRIMARY
,至少对于行数而言。
我已将表内容复制到第二台服务器。该服务器速度更快,而且复制后当然会生成一个漂亮、紧凑的表,不会发生删除和更新。因此,在新服务器上一切都很好、很快,但旧服务器的行为仍然让我感到困惑:
我有一个索引,并且已经在表上定义了PRIMARY
另一个索引(称为)。在旧服务器(MySQL 5.0.27)上,我可以看到它将使用索引。查询需要一分钟以上。如果我,则需要约 100 毫秒。如果我把它也选择更快的索引。index2
EXPLAIN SELECT COUNT(*) FROM myTable
PRIMARY
SELECT COUNT(*) FROM myTable USE INDEX(index2)
WHERE someCol > lowest_possible_value
在新服务器 (MySQL 5.1.52) 上,相同的EXPLAIN
语句告诉我它将使用index2
,没有任何提示。简单的SELECT COUNT(*) FROM myTable
非常快,大约 20-30 毫秒。我可以运行SELECT COUNT(*) FROM myTable USE INDEX(PRIMARY)
,以强制它使用“坏”索引,并且它需要更长的时间 - 仅 3-4 秒,但正如我所说,还有其他差异可以解释这一点,这仍然比“好”(非)索引慢一百倍以上PRIMARY
。
为什么较新的 MySQL 实例会选择“正确”的索引?我可以在旧服务器上执行某些操作来重现此行为吗?我现在想避免进行全面升级,但这并非不可能。
答案1
两种可能性:
- 事实上,它是一个新表,这意味着 MySQL 用来尝试估计哪个索引是正确的索引的统计数据是不同的。
- 新版本的 MySQL 更加智能。
修复前者可能很简单ANALYZE TABLE
;修复后者只需进行软件包升级即可。