为什么从table_name中选择count(*)这么慢?

时间:2019-04-04 02:51:47

标签: mysql sql count

mysql> select count(*)
    -> from ip_address_varchar20;
+----------+
| count(*) |
+----------+
|  2764687 |
+----------+
1 row in set (1 min 28.80 sec)

我认为应该有一个字段来存储任何表的大小,但是我发现count(*)太慢了。

为什么DBMS无法对此进行优化?还是我对此做了一些不好的做法?

2 个答案:

答案 0 :(得分:1)

发件人:https://wiki.postgresql.org/wiki/Why_PostgreSQL_Instead_of_MySQL:_Comparing_Reliability_and_Speed_in_2007

  

已知PostgreSQL执行缓慢的一项操作正在执行   表中的全部行数,通常使用此SQL:

     

从表中选择COUNT(*)

     

之所以如此缓慢,是因为MVCC在   PostgreSQL。多个交易可以看到不同的事实   数据状态意味着没有直接的方法可以   “ COUNT(*)”汇总整个表中的数据; PostgreSQL必须   从某种意义上讲,遍历所有行。这通常会导致   顺序扫描读取有关表中每一行的信息。

以上关于Postgres的解释也适用于MySQL的InnoDB。由于InnoDB使用MVCC。

有些approaches可以对InnoDB进行快速计数。例如,您可以使用估算值,也可以使用触发器来维护表格的行数。

答案 1 :(得分:-1)

某些数据库确实在外部存储表的大小。但是,大多数数据库都直接或通过索引读取所有数据,以满足COUNT()查询。

这可确保对行进行准确计数。它还考虑了事务语义。