本文已收录在Github,关注我,紧跟本系列专栏文章,咱们下篇再续!
为统计记录数,由SELECT返回。假如有如下数据:
employee_tbl表:
id | name | work_date | daily_typing_pages |
---|---|---|---|
1 | John | 2007-01-24 | 250 |
2 | Ram | 2007-05-27 | 220 |
3 | Jack | 2007-05-06 | 170 |
3 | Jack | 2007-04-06 | 100 |
4 | Jill | 2007-04-06 | 220 |
5 | Zara | 2007-06-06 | 300 |
5 | Zara | 2007-02-06 | 350 |
统计行的总数:
select count(*) from employee_tbl;
7
计算 Zara 的记录数
select count(*) from employee_tbl
where name="Zara";
count(*)
2
count(*)
是检索表中所有记录行的数目,无论是否包含null值count(字段),检索表中的该字段的非空行数,即不统计该字段值为null的记录。
SELECT COUNT(1) FROM tablename
类似:
SELECT COUNT(*) FROM tablename WHERE COL = 'value'
SELECT COUNT(COL) FROM tablename WHERE COL2 = 'value'
count(*)
快count(*)
快count(1)跟count(主键)一样,只扫描主键
count(*)跟count(非主键)一样,扫描整个表
明显前者更快。
表数据量大,对表分析后,用count(1)还要比用count()用时多!
执行计划看,count(1)和count(*)
效果一样。 但表做过分析后,count(1)会比count(*)的用时少些(1w以内数据量),差不太多。
若count(1)是聚合索引id,那肯定count(1)快。但差的很小。
因为count(*)
会自动优化指定到那一个字段。所以没必要去count(1),用count(*)
,sql会帮你完成优化。
因此:count(1)和count(*)基本无差。
count(*)
create table counttest(name char(1), age char(2));
mysql> select * from counttest;
+------+------+
| name | age |
+------+------+
| a | 14 |
| a | 15 |
| a | 15 |
| b | NULL |
| b | 16 |
| c | 17 |
| d | NULL |
| e | |
+------+------+
8 rows in set (0.00 sec)
mysql> select name, count(name), count(1), count(*), count(age), count(distinct(age))
-> from counttest
-> group by name;
+------+-------------+-----------+----------+------------+-------------------+
| name | count(name) | count(1) | count(*) | count(age) | count(distinct(age)) |
+------+-------------+-----------+----------+------------+-------------------+
| a | 3 | 3 | 3 | 3 | 2 |
| b | 2 | 2 | 2 | 1 | 1 |
| c | 1 | 1 | 1 | 1 | 1 |
| d | 1 | 1 | 1 | 0 | 0 |
| e | 1 | 1 | 1 | 0 | 0 |
+------+-------------+-----------+----------+------------+-------------------+
5 rows in set (0.00 sec)
MyISAM有表元数据的缓存,例如行,即COUNT(*)
值,对于MyISAM表的COUNT(*)
无需消耗太多资源,但对于Innodb,就没有这种元数据,CONUT(*)
执行较慢。