当我第一次开始使用MySQL时,select count(*)
或select count(1)
几乎是即时的。但是我现在正在使用Dreamhost上安装的5.6.25版本,有时需要20-30秒才能完成select count(1)
。然而,第二次它很快 - 就像索引被缓存一样---但不是超快速,就像数据来自元数据索引一样。
任何人都明白发生了什么,以及为什么会发生变化?
mysql> select count(1) from times;
+----------+
| count(1) |
+----------+
| 1511553 |
+----------+
1 row in set (22.04 sec)
mysql> select count(1) from times;
+----------+
| count(1) |
+----------+
| 1512007 |
+----------+
1 row in set (0.54 sec)
mysql> select version();
+------------+
| version() |
+------------+
| 5.6.25-log |
+------------+
1 row in set (0.00 sec)
mysql>
答案 0 :(得分:4)
我猜你第一次开始使用MyISAM,现在你正在使用InnoDB。 InnoDB只是不存储这些信息。请参阅文档:Limits on InnoDB Tables
InnoDB没有在表中保留行的内部计数,因为并发事务可能同时“看到”不同数量的行。为了处理SELECT COUNT(*)FROM t语句,InnoDB扫描表的索引,如果索引不完全在缓冲池中,则需要一些时间。要快速计数,您必须使用自己创建的计数器表,并让应用程序根据插入和删除更新它。如果大概行数足够,可以使用SHOW TABLE STATUS。请参见第9.5节“优化InnoDB表”。
因此,当(较慢的)第一个查询之后索引完全位于缓冲池中时,第二个查询再次快速。
MyISAM并不需要关心并发事务可能会产生的问题,因为它不支持事务,因此select count(*) from t
只会查找并快速返回存储的值。 / p>