这是一个出乎意料的大性能差异,但我可以想到一些可能造成的原因。
历史上,MyISAM被认为比InnoDB更快,但对于最近版本的InnoDB来说,这只适用于非常少量的使用情况。MyISAM通常对于只读表的表扫描更快。在大多数其他用例中,我通常发现InnoDB要快得多。往往快得多。在大多数MySQL用法中,表锁定对MyISAM来说是致命的。
MyISAM将索引缓存在其键缓冲区中。也许您将键缓冲区设置得太小了,以至于它无法有效地缓存相当大的表的索引。
MyISAM依赖于操作系统从OS磁盘高速缓存中缓存表数据。如果操作系统内存不足,它将开始转储其磁盘高速缓存。这可能会迫使它继续从磁盘中读取。
InnoDB在其自己的内存缓冲区中同时缓存索引和数据。如果将innodb_flush_method设置为O_DIRECT,则可以告诉操作系统不要使用其磁盘高速缓存,尽管此功能在OS X上不受支持。
InnoDB通常以16kb页面缓冲数据和索引。根据您在查询之间更改@eid值的方式,由于来自前一个查询的磁盘读取,它可能已经缓存了一个查询的数据。
确保创建的索引完全相同。使用explain检查MySQL是否使用索引。由于您包含了描述的输出而不是show create table或show indexes from的输出,因此我无法确定entity_id是否是复合索引的一部分。如果它不是复合索引的第一部分,则不会使用它。
如果您正在使用相对较新的MySQL版本,请在运行查询之前运行以下命令:
set profiling = 1;
这将为您的会话打开查询分析功能。运行查询后,运行
show profiles;
这将显示可用配置文件的查询列表。默认情况下,我认为它保留了最近的20个。假设您的查询是第一个,请运行:
show profile for query 1;
接下来,您将看到运行查询的每个阶段的持续时间。这对于确定是什么(例如,表锁定、排序、创建临时表等)导致查询变慢非常有用。