【黄啊码】MySQL中NULL和““的区别以及对索引的影响

举报
黄啊码 发表于 2022/06/28 23:16:45 2022/06/28
【摘要】 定义和区别 定义:空值(NULL)的长度是NULL,不确定占用了多少存储空间,但是占用存储空间的空字符串(’’)的长度是0,是不占用空间的区别:在进行count()统计某列时候,如果用null值系统会自动忽略掉,但是空字符会进行统计。不过count(*)会被优化,直接返回总行数,包括null值。判断null用is null或is no...

定义和区别


  
  1. 定义:
  2. 空值(NULL)的长度是NULL,不确定占用了多少存储空间,但是占用存储空间的
  3. 空字符串(’’)的长度是0,是不占用空间的
  4. 区别:
  5. 在进行count()统计某列时候,如果用null值系统会自动忽略掉,但是空字符会进行统计。
  6. 不过count(*)会被优化,直接返回总行数,包括null值。
  7. 判断nullis nullis not nullSQL可以使用ifnull()函数进行处理;
  8. 判断空字符用=''或者!=''进行处理。
  9. 对于timestamp数据类型,插入null值会是当前系统时间;
  10. 插入空字符,则出现0000-00-00 00:00:00

实例:


  
  1. CREATE TABLE test_ab (id int,
  2. col_a varchar(128),
  3. col_b varchar(128) not null
  4. );
  5. insert test_ab(id,col_a,col_b) values(1,1,1);
  6. insert test_ab(id,col_a,col_b) values(2,'','');
  7. insert test_ab(id,col_a,col_b) values(3,null,'');
  8. insert test_ab(id,col_a,col_b) values(4,null,1);
  9. mysql> select * from test_ab;
  10. +------+-------+-------+
  11. | id | col_a | col_b |
  12. +------+-------+-------+
  13. | 1 | 1 | 1 |
  14. | 2 | | |
  15. | 3 | NULL | |
  16. | 4 | NULL | 1 |
  17. +------+-------+-------+
  18. 4 rows in set (0.00 sec)
  • 首先比较一下,空字符(’’)和空值(null)查询方式的不同:

  
  1. mysql> select * from test_ab where col_a = '';
  2. +------+-------+-------+
  3. | id | col_a | col_b |
  4. +------+-------+-------+
  5. | 2 | | |
  6. +------+-------+-------+
  7. 1 row in set (0.00 sec)
  8. mysql> select * from test_ab where col_a is null;
  9. +------+-------+-------+
  10. | id | col_a | col_b |
  11. +------+-------+-------+
  12. | 3 | NULL | |
  13. | 4 | NULL | 1 |
  14. +------+-------+-------+
  15. 2 rows in set (0.00 sec)

 由此可见,null''的查询方式不同。而且比较字符 ‘=’’>’ ‘<’ ‘<>’不能用于查询null,
如果需要查询空值(null),需使用is null 和is not null。

  • 第二种比较,参与运算

  
  1. mysql> select col_a+1 from test_ab where id = 4;
  2. +---------+
  3. | col_a+1 |
  4. +---------+
  5. | NULL |
  6. +---------+
  7. 1 row in set (0.00 sec)
  8. mysql> select col_b+1 from test_ab where id = 4;
  9. +---------+
  10. | col_b+1 |
  11. +---------+
  12. | 2 |
  13. +---------+
  14. 1 row in set (0.00 sec)

 由此可见,空值(null)不能参与任何计算,因为空值参与任何计算都为空。
所以,当程序业务中存在计算的时候,需要特别注意。
如果非要参与计算,需使用ifnull函数,将null转换为''才能正常计算。

  • 第三种比较,统计数量

  
  1. mysql> select count(col_a) from test_ab;
  2. +--------------+
  3. | count(col_a) |
  4. +--------------+
  5. | 2 |
  6. +--------------+
  7. 1 row in set (0.00 sec)
  8. mysql> select count(col_b) from test_ab;
  9. +--------------+
  10. | count(col_b) |
  11. +--------------+
  12. | 4 |
  13. +--------------+
  14. 1 row in set (0.00 sec)

 由此可见,当统计数量的时候。空值(null)并不会被当成有效值去统计。同理,sum()求和的时候,null也不会被统计进来,这样就能理解,为什么null计算的时候结果为空,而sum()求和的时候结果正常了。

 为什么Mysql 数据库尽量避免NULL?

(1)如果查询中包含可为NULL的列,对Mysql来说更难优化,因为可为NULL的列使得索引,索引统计和值比较都更复杂。
(2)含NULL复合索引无效.
(3)可为NULL的列会使用更多的存储空间,在Mysql中也需要特殊处理。
(4)当可为NULL的列被索引时,每个索引记录需要一个额外的字节,在MyISAM里甚至还可能导致固定大小的索引(例如只有一个整数列的索引)变成可变大小的索引。

MySQL索引失效的几种清空

1.索引不存储null值

更准确的说,单列索引不存储null值,复合索引不存储全为null的值。索引不能存储Null,所以对这列采用is null条件时,因为索引上根本

没Null值,不能利用到索引,只能全表扫描。

为什么索引列不能存Null值?

将索引列值进行建树,其中必然涉及到诸多的比较操作。Null值的特殊性就在于参与的运算大多取值为null。

这样的话,null值实际上是不能参与进建索引的过程。也就是说,null值不会像其他取值一样出现在索引树的叶子节点上。

2.不适合键值较少的列(重复数据较多的列)

假如索引列TYPE有5个键值,如果有1万条数据,那么 WHERE TYPE = 1将访问表中的2000个数据块。

再加上访问索引块,一共要访问大于200个的数据块。

如果全表扫描,假设10条数据一个数据块,那么只需访问1000个数据块,既然全表扫描访问的数据块

少一些,肯定就不会利用索引了。

3.前导模糊查询不能利用索引(like '%XX'或者like '%XX%')

假如有这样一列code的值为'AAA','AAB','BAA','BAB' ,如果where code like '%AB'条件,由于前面是

模糊的,所以不能利用索引的顺序,必须一个个去找,看是否满足条件。这样会导致全索引扫描或者全表扫

描。如果是这样的条件where code like 'A % ',就可以查找CODE中A开头的CODE的位置,当碰到B开头的

数据时,就可以停止查找了,因为后面的数据一定不满足要求。这样就可以利用索引了。

4.索引失效的几种情况

1.如果条件中有or,即使其中有条件带索引也不会使用(这也是为什么尽量少用or的原因)

要想使用or,又想让索引生效,只能将or条件中的每个列都加上索引

2.对于多列索引,不是使用的第一部分,则不会使用索引

3.like查询以%开头

4.如果列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不使用索引

5.如果mysql估计使用全表扫描要比使用索引快,则不使用索引

5.MySQL主要提供2种方式的索引:B-Tree索引,Hash索引

B树索引具有范围查找和前缀查找的能力,对于有N节点的B树,检索一条记录的复杂度为O(LogN)。相当于二分查找。

哈希索引只能做等于查找,但是无论多大的Hash表,查找复杂度都是O(1)。

显然,如果值的差异性大,并且以等值查找(=、 、in)为主,Hash索引是更高效的选择,它有O(1)的查找复杂度。

如果值的差异性相对较差,并且以范围查找为主,B树是更好的选择,它支持范围查找。

文章来源: markwcm.blog.csdn.net,作者:黄啊码,版权归原作者所有,如需转载,请联系作者。

原文链接:markwcm.blog.csdn.net/article/details/123710942

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。