1. COUNT
官网:COUNT(expr)
1.1 count(*)、count(1)和count(列名)的区别
执行效果上:
- count(*) 包括了所有的列,相当于行数,在统计结果的时候,不会忽略列值为NULL ;
- count(1) 包括了忽略所有列,用1代表代码行,在统计结果的时候,不会忽略列值为NULL ;count(1)与count(8)以及count(400)的结果一致
- count(列名)只包括列名那一列,在统计结果的时候,会忽略列值为空(这里的空不是只空字符串或者0,而是表示null)的计数,即某个字段值为NULL时,不统计。
示例:
mysql> select * from account;
+----------------+---------+
| account_number | balance |
+----------------+---------+
| A | 1000 |
| B | 500 |
| D | 1000 |
| E | 1000 |
| NULL | NULL |
| E | NULL |
| NULL | 444 |
| NULL | 54343 |
+----------------+---------+
8 rows in set (0.00 sec)
mysql> select count(1),count(*),count('dd'),count(balance),count(account_number) from account;
+----------+----------+-------------+----------------+-----------------------+
| count(1) | count(*) | count('dd') | count(balance) | count(account_number) |
+----------+----------+-------------+----------------+-----------------------+
| 8 | 8 | 8 | 6 | 5 |
+----------+----------+-------------+----------------+-----------------------+
1 row in set (0.00 sec)
可以看到 count(1),count(*),count(‘dd’)对于NULL值都进行了统计,而count(列名)则没有统计NULL值。
执行效率上:
-
列名为主键,count(列名)会比count(1)快
-
列名不为主键,count(1)会比count(列名)快
-
如果表多个列并且没有主键,则 count(1) 的执行效率优于 count(*)
-
如果有主键,则 select count(主键)的执行效率是最优的
-
如果表只有一个字段,则 select count(*)最优。
2. MySQL获取表中列的信息
这三个语句的执行结果是一样的
1. explain t_service_publish_info;
2. desc t_service_publish_info;
3. show columns from t_service_publish_info;
3. EXPLAIN解析执行计划
官网链接:https://dev.mysql.com/doc/refman/8.0/en/explain-output.html
示例:
mysql> explain select f_org_id from t_service_publish_info where f_service_publish_info_id ='014b7435-0b47-411c-8725-f9e6b4c118ca'
-> union select count(f_service_publish_info_id) from t_service_publish_info;
+----+--------------+------------------------+------------+-------+---------------+---------+---------+-------+------+----------+------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+--------------+------------------------+------------+-------+---------------+---------+---------+-------+------+----------+------------------------------+
| 1 | PRIMARY | t_service_publish_info | NULL | const | PRIMARY | PRIMARY | 767 | const | 1 | 100.00 | NULL |
| 2 | UNION | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Select tables optimized away |
| NULL | UNION RESULT | <union1,2> | NULL | ALL | NULL | NULL | NULL | NULL | NULL | NULL | Using temporary |
+----+--------------+------------------------+------------+-------+---------------+---------+---------+-------+------+----------+------------------------------+
3 rows in set, 1 warning (0.02 sec)
这篇文章中对每个字段进行了详细解释《数据库查询优化:使用explain分析sql语句执行效率》
针对自己结果对部分属性进行了解:
1. id : select 的查询序列号
2. select_type:select的类型
PRIMARY:最外面的SELECT
UNION:UNION中的第二个或后面的SELECT语句
UNION RESULT:UNION的结果
3. table: 显示这行数据是关于那张表的;
<unionM,N>:该行是指具有id值的行 的 M并集 N
4. partition:查询将从中匹配记录的分区
5. type:显示连接使用了哪种类别,有无使用索引,是使用explain分析性能的关键项。
结果从好到坏依次是:
system > const > eq_ref > ref > fulltext > ref_or_null
> index_merge > unique_subquery > index_subquery
> range > index > ALL
最好是到ref~range级别,低于的话会出现性能问题。
const:当确定最多只会有一行匹配的时候,MySQL优化器会在查询前读取它而且只读取一次,因此非常快。
使用主键查询往往就是 const 级别的,非常高效。
ALL: 全表扫描
6. possible_keys:列指出MySQL能使用哪个索引在该表中找到行
7. key:显示MySQL实际决定使用的键(索引)。
如果没有选择索引,键是NULL
8. key_len:显示MySQL决定使用的键长度。
如果键是NULL,则长度为NULL。
使用的索引的长度。在不损失精确性的情况下,长度越短越好
9. ref:显示使用哪个列或常数与key一起从表中选择行。
10. rows:显示MySQL认为它执行查询时必须检查的行数。
11. filtered:表通过条件过滤的表行的估计百分比。
最大值为100,这表示未过滤行。
12、Extra:包含MySQL解决查询的详细信息,也是关键参考项之一。
using temporary:表示需要临时表来存储结果
Select tables optimized away:SELECT操作已经优化到不能再优化了。
官方释义是:当在优化阶段就可以读取要读取的行时(例如,通过读取索引行),则在查询执行期间无需读取任何表。