mysql count null_Python 之 MySql“未解之谜”13--都是 NULL 惹的祸(上)

afe164ce3781f0ce5c3850e0a8f210c7.gif
a3f72ae61bbbbce914cbf87ffda2fb9a.png

NULL 和 空值的区别

● 本质区别

空值不占空间,用''表示

NULL 值占空间,用NULL表示

空值代表杯子是真空的,NULL 代表杯子中装满了空气,2 个杯子看起来一样,但是有本质的区别

b4dfe8b872c7f16a32c3a19843821acd.png

MySql 官方:

“NULL columns require additional space in the row to record whether their values are NULL. For MyISAM tables, each NULL column takes one bit extra, rounded up to the nearest byte.”

NULL 占空间


NULL 和 空值的保存问题

以 varchar 类型

● 如果字段是 NOT NULL

可以保存空值,不能保存 NULL值

● 如果字段是 NULL

可以保存空值和 NULL 值

字段类型是 NOT NULL,为什么可以插入空值?

NULL 表示未知,没有类型可言,而 '' 是有类型的,表示一个空的字符串。所以有NOT NULL 约束的列是可以插入 '' 的。


NULL 和空值对聚合函数的影响

● COUNT(expr)

在进行 COUNT(expr) 统计某列的记录数的时候,如果采用的是 NULL 值,系统会自动忽略,但是空值是会进行统计到其中的

0b7b7524858411bc5ec307de352e6661.png

>>> SELECT COUNT(NAME) FROM USER ;

>>> 3

● AVG(expr)

name 是 varchar 类型

d68ac25114f68ce55e818d30babb8d88.png

>>>SELECT AVG(NAME) FROM USER ;

>>>2.25

我们可以看出:MySql 在计算 AVG(expr) 时 会自动将 NULL 值过滤掉不参与计算,但是不排除空值

● MIN(expr)

>>>SELECT MIN(NAME) FROM USER ;

>>>''

我们可以看出:MySql 在计算 MIN(expr) 时 会自动将 NULL 值过滤掉不参与计算,但是不排除空值


NULL 和空值对 order by 和 group by 的影响

5c282925d735e96e7f45123de6ba209c.png

原表

>>> SELECT * FROM USER ORDER BY NAME;

ea859c4d1584498f85c5795625c58853.png

>>> SELECT * FROM USER GROUP BY NAME;

0ec990b92402e50a598a843a2039eaa5.png

MySql 对空值或者 NULL 的判断

围观下《阿里巴巴开发手册》中 MySql 部分描述

●【强制】使用 ISNULL()来判断是否为 NULL 值

说明:NULL 与任何值的直接比较都为 NULL

1) NULL<>NULL 的返回结果是 NULL,而不是 false

2) NULL=NULL 的返回结果是 NULL,而不是 true

3) NULL<>1 的返回结果是 NULL,而不是 true

注意:

ISNULL (expr) 函数:如果 expr 为 null 返回 1,否则返回 0;ISNULL (expr) = 0 不会排除空值;使用 <> 查询时,会筛选掉空值和 NULL 值。


NULL 对索引的影响

结论看第 3 点

42a78e82ef6f50daeb595293f417039a.png

1、给 a 列增加索引 idx_a,a 列可以为 NULL

测试数据总量为 10w 条数据,其中有一条记录 a 列为 NULL的测试数据

● 查询所有列

① WHERE 条件中 IS NULL

86e1c2725fc68f3ad95371180e424201.png
e71e19718f9300e9214257143e65a95c.png

type : ref (非唯一性索引)

key : idx_a

可以看出 WHERE 条件使用 IS NULL ,查询所有列使用 idx_a ,type 为 ref。

② WHERE 条件中 IS NOT NULL

0202d0889f4ac4127e9f4488459d376f.png
88b1d520480c16a1aba0d97bfbc8d837.png

type : ALL

key : (NULL)

可以看出 WHERE 条件使用 IS NOT NULL ,全表扫描,未走索引。


查询索引列

① WHERE 条件中 IS NULL

32fb8b3c1694eee624a26361a5760a33.png
ad653d4e553c69381e64407a7ef72067.png

type : ref (非唯一性索引)

key : idx_a

可以看出 where 条件使用 is null ,查询所有列使用 idx_a ,type 为 ref

② WHERE 条件中 IS NOT NULL

0202d0889f4ac4127e9f4488459d376f.png
b007edec3fe69d73f9aba62b93612984.png

可以看出 where 条件使用 is not null ,查询所有列使用 idx_a ,type 为 range。


2、给 a 列增加索引 idx_a,a 列可以为 NOT NULL

● 查询所有列

① WHERE 条件中 IS NULL

无意义,不会使用索引。

Extra 显示:Impossible WHERE

② WHERE 条件中 IS NOT NULL

0202d0889f4ac4127e9f4488459d376f.png

全表扫描


● 查询索引列

① WHERE 条件中 IS NULL

无意义,不会使用索引。

Extra 显示:Impossible WHERE

② WHERE 条件中 IS NOT NULL

64ff34155f3682e50a5c8c7d2e562fb0.png

可以看出 where 条件使用 is not null ,查询所有列使用 idx_a ,type 为 index。


3、汇总

注:当 a 列为 NOT NULL 且建立 idx_a 索引,无论 WHERE 后时 IS NULL 还是 IS NOT NULL,相当于“脱裤子放屁”,参考价值不大。主要研究当 a 列为 NULL 且建立 idx_a 索引,在MySql 5.7 版本使用 InnoDB 存储引擎

结论如下:

f63d9e29d49dcc50b8691479b9107ea9.png
cd0dd628df0309d9dbb2a97979192eea.png
56ec30c4aaa121b6df659ae175554cc6.png

>>>Python 之 MySql“未解之谜”12--一个*号引发的思考

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值