MySQL:大表行数查询


#MySQL 笔记


基于 InnoDB 存储引擎的表,在数据量很大之后,用 count 查询函数会变得很慢。

我们新建一张表进行测试(测试结果因硬件配置不同,会有所差异):

USE test;
CREATE TABLE `test_table` (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `name` varchar(32) NOT NULL DEFAULT '' COMMENT '名字',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

参考 MySQL:使用 load data 快速导入数据 ,在 test_table 中插入 1999_9999 条数据。

方案1

使用 count :

mysql> select count(*) from test_table;
+----------+
| count(*) |
+----------+
| 19999999 |
+----------+
1 row in set
Time: 3.437s

耗时 3.4 秒。

方案2

mysql> SELECT SQL_CALC_FOUND_ROWS id FROM test_table limit 1;
+----+
| id |
+----+
| 1  |
+----+
1 row in set
Time: 3.707s

mysql> SELECT found_rows() AS result;
+--------+
| result |
+--------+
| 1      |
+--------+
1 row in set
Time: 0.006s

耗时还是比较长。

方案3: 预估值

使用下面的 SQL:

select TABLE_NAME, TABLE_ROWS
from  
    INFORMATION_SCHEMA.PARTITIONS  
where 
    TABLE_SCHEMA = 'test' 
    and TABLE_NAME='test_table';

结果为:

+------------+------------+
| TABLE_NAME | TABLE_ROWS |
+------------+------------+
| test_table | 19508174   |
+------------+------------+

19508174 是一个预估的值。

方案4:预估

因为主键id是逐渐加1递增的,在确保表中数据几乎没有跳id、删数据的情况下,直接用最大id,减最小id:

mysql> select id from test_table order by id asc limit 1;
+----+
| id |
+----+
| 1  |
+----+
1 row in set
Time: 0.006s

mysql> select id from test_table order by id desc limit 1;
+----------+
| id       |
+----------+
| 19999999 |
+----------+

19999999 - 1 + 1 = 19999999 ,所以该表约有 19999999 条数据。



( 本文完 )