为什么MySQL在不同的版本中对我的查询使用不同的索引?

我有一个大型的InnoDB表(大约800MB),我想计算行数。 我知道SELECT COUNT(*)在InnoDB中有问题,但是我所看到的解决scheme之一是创build一个二级索引 ,这比通过PRIMARY咀嚼的速度快得多,至less对于行数来说。

我已经将表内容复制到第二个服务器。 服务器的速度更快,当然复制产生了一个很好的,紧凑的表,没有遭受删除和更新。 所以在新的服务器上一切都很好,但是关于旧服务器的行为还是令我困惑:

我有一个PRIMARY索引,另一个索引(称为index2 )已经在表上定义。 在旧的服务器上(MySQL 5.0.27),我可以解释EXPLAIN SELECT COUNT(*) FROM myTable ,看到它将使用PRIMARY索引。 查询需要一分钟。 如果我SELECT COUNT(*) FROM myTable USE INDEX(index2) ,它需要SELECT COUNT(*) FROM myTable USE INDEX(index2) 。 如果我把WHERE someCol > lowest_possible_value它也select更快的指标。

在新的服务器(MySQL 5.1.52)上,同样的EXPLAIN语句告诉我它将使用index2 ,而没有任何提示。 一个简单的SELECT COUNT(*) FROM myTable非常快,大约20-30ms。 我可以运行SELECT COUNT(*) FROM myTable USE INDEX(PRIMARY) ,强制它使用“坏”索引,它需要更长的时间 – 只有3-4秒,但正如我所说的还有其他的差异来说明,这比“好”(非PRIMARY )指数还要慢上百倍。

为什么新的MySQL实例select“正确的”索引? 我可以在旧服务器上做些什么来重现这种行为? 我想避免一个完整的升级,但这不是没有问题的。

两种可能性:

  1. 这是一个新表的事实意味着MySQL用来尝试和估计哪个索引是正确使用的统计信息是不同的。
  2. 较新版本的MySQL更聪明。

修正前者可能与ANALYZE TABLE一样简单; 修复后者只是一个包升级。