基于 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 条数据。