mysql字段为NULL索引是否会失效实例详解


Posted in MySQL onMay 30, 2022

项目场景:

很多博客说mysql在字段中创建普通索引,如果该索引中的数据存在null值是不走索引这个结论是错误的,不过尽量还是设置默认值。(版本8.0低于这个版本可能结果不一致)

1、创建表sc_base_color,其中普通索引为 “name,group_num”,这里暂时不测组合索引,下面再测试。

CREATE TABLE `sc_base_color` (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `group_num` bigint DEFAULT NULL COMMENT '颜色代码',
  `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '颜色名称',
  PRIMARY KEY (`id`) USING BTREE,
  KEY `idx_name` (`name`),
  KEY `idx_group_num` (`group_num`)
) ENGINE=InnoDB AUTO_INCREMENT=574 DEFAULT CHARSET=utf8mb3 COMMENT='颜色';

2、初始化测试数据

INSERT INTO `sc_base_color`(`id`, `group_num`, `name`) VALUES (30, 1, '米黄');
INSERT INTO `sc_base_color`(`id`, `group_num`, `name`) VALUES (31, 1, '黑色');
INSERT INTO `sc_base_color`(`id`, `group_num`, `name`) VALUES (32, 1, NULL);
INSERT INTO `sc_base_color`(`id`, `group_num`, `name`) VALUES (33, 1, '白色');
INSERT INTO `sc_base_color`(`id`, `group_num`, `name`) VALUES (34, 1, NULL);
INSERT INTO `sc_base_color`(`id`, `group_num`, `name`) VALUES (35, 1, '绿色');
INSERT INTO `sc_base_color`(`id`, `group_num`, `name`) VALUES (36, NULL, NULL);
INSERT INTO `sc_base_color`(`id`, `group_num`, `name`) VALUES (37, NULL, NULL);
INSERT INTO `sc_base_color`(`id`, `group_num`, `name`) VALUES (38, NULL, NULL);
INSERT INTO `sc_base_color`(`id`, `group_num`, `name`) VALUES (39, NULL, NULL);
INSERT INTO `sc_base_color`(`id`, `group_num`, `name`) VALUES (40, NULL, '紫色');
INSERT INTO `sc_base_color`(`id`, `group_num`, `name`) VALUES (41, NULL, NULL);
INSERT INTO `sc_base_color`(`id`, `group_num`, `name`) VALUES (42, NULL, NULL);
INSERT INTO `sc_base_color`(`id`, `group_num`, `name`) VALUES (43, NULL, NULL);
INSERT INTO `sc_base_color`(`id`, `group_num`, `name`) VALUES (44, NULL, '蓝色');
INSERT INTO `sc_base_color`(`id`, `group_num`, `name`) VALUES (45, NULL, NULL);
INSERT INTO `sc_base_color`(`id`, `group_num`, `name`) VALUES (46, NULL, NULL);
INSERT INTO `sc_base_color`(`id`, `group_num`, `name`) VALUES (47, 2, '米蓝色');
INSERT INTO `sc_base_color`(`id`, `group_num`, `name`) VALUES (48, 2, NULL);
INSERT INTO `sc_base_color`(`id`, `group_num`, `name`) VALUES (49, 2, NULL);
INSERT INTO `sc_base_color`(`id`, `group_num`, `name`) VALUES (50, 2, '黑红色');

3、测试普通索引为NULL的情况是否使用了索引

使用 = 查询,测试结果中使用到了索引,其中索引字段的值为“NULL”

EXPLAIN select * from sc_base_color where name = '米黄';
EXPLAIN select * from sc_base_color where group_num = 1;

截图结果,两列数据都存在空,最终走了索引。

mysql字段为NULL索引是否会失效实例详解

使用 大于、小于 查询

EXPLAIN select * from sc_base_color where name > '米黄';
EXPLAIN select * from sc_base_color where name < '米黄';

截图结果

mysql字段为NULL索引是否会失效实例详解

使用 不等于、not in 、isnull、!isnull查询

EXPLAIN select * from sc_base_color where group_num != 1;
EXPLAIN select * from sc_base_color where group_num not in (1);
EXPLAIN select * from sc_base_color where  isnull(group_num);
EXPLAIN select * from sc_base_color where  !isnull(group_num);

截图结果

mysql字段为NULL索引是否会失效实例详解

使用isnull、is not null查询

# 使用is not null可能会导致索引失效,我测试了20条数据,只要null值占全部数据的百分之50就不会失效,否则会失效。又测了40条数据,23条数据不会为空,22条为null的会为空
EXPLAIN select  * from sc_base_color where  group_num is not null;
# 使用is null也可能会导致索引失效,我测试了20条数据,6数数据不为空不会失效,也就是可能当空的数据占比70%的时候索引会失效。
EXPLAIN select  * from sc_base_color where  group_num is  null;

由此可以得出结论,字段为空是可以走索引的,但是部分场景可能会失效,尽量还是给默认值。

4、测试组合索引为NULL是否走了索引

先删除普通索引字段,增加组合索引

ALTER TABLE sc_base_color DROP INDEX idx_group_num;
ALTER TABLE sc_base_color DROP INDEX idx_name;
alter table `sc_base_color` add index idx_group_num_idx_name (group_num, name);

测试 = > < 查询结果

EXPLAIN select  * from sc_base_color where  group_num > 1;
EXPLAIN select  * from sc_base_color where  group_num < 1;
EXPLAIN select  * from sc_base_color where  group_num = 1;
EXPLAIN select  * from sc_base_color where group_num = 1 and name = '米黄';

截图结果,是可以走索引的,下面的逻辑就不用测试了和普通索引一样,除非不符合最左匹配原则直接查询name字段。

mysql字段为NULL索引是否会失效实例详解

5、总结

在设计数据库的时候尽量还是给字段的默认值。

1、比如int、bigint类型默认值为-1/0

2、比如varchar类型默认值为空串

3、bigdecimal类型为0等等。

NULL值会有不少坑

1、count(字段NULL)会过滤统计的数据,sum这些函数也会

2、使用> < 的时候也会过滤掉为NULL的数据

3、group by 的时候会把所有为NULL的数据合并,可以随机生成UUID解决

4、还有场景可能也有问题,这里我也忘记了,用的时候才会想起来。

总结

到此这篇关于mysql字段为NULL索引是否会失效的文章就介绍到这了!


Tags in this post...

MySQL 相关文章推荐
jdbc使用PreparedStatement批量插入数据的方法
Apr 27 MySQL
解决MySQL存储时间出现不一致的问题
Apr 28 MySQL
详解MySQL主从复制及读写分离
May 07 MySQL
my.ini优化mysql数据库性能的十个参数(推荐)
May 26 MySQL
MySQL Router实现MySQL的读写分离的方法
May 27 MySQL
如何自己动手写SQL执行引擎
Jun 02 MySQL
MySQL 服务和数据库管理
Nov 11 MySQL
mysql中如何用命令创建联合唯一索引
Apr 20 MySQL
在MySQL中你成功的避开了所有索引
Apr 20 MySQL
MySQL详解进行JDBC编程与增删改查方法
Jun 16 MySQL
mysql数据库隔离级别详解
Jun 16 MySQL
MySQL 原理与优化之Update 优化
Aug 14 MySQL
MYSQL如何查看操作日志详解
sql查询语句之平均分、最高最低分及排序语句
May 30 #MySQL
mysql5.5中文乱码问题解决的有用方法
深入理解MySQL中MVCC与BufferPool缓存机制
MYSQL事务的隔离级别与MVCC
详解Mysql数据库平滑扩容解决高并发和大数据量问题
MySQL中EXPLAIN语句及用法
May 20 #MySQL
You might like
php获取新浪微博数据API实例
2013/11/12 PHP
PHP对象克隆clone用法示例
2016/09/28 PHP
PHP设计模式(五)适配器模式Adapter实例详解【结构型】
2020/05/02 PHP
JavaScript 特殊字符
2007/04/05 Javascript
js 实现打印网页中定义的部分内容的代码
2010/04/01 Javascript
Firefox/Chrome/Safari的中可直接使用$/$$函数进行调试
2012/02/13 Javascript
Extjs单独定义各组件的实例代码
2013/06/25 Javascript
jQuery获得页面元素的绝对/相对位置即绝对X,Y坐标
2014/03/06 Javascript
浅析JQuery中的html(),text(),val()区别
2014/09/01 Javascript
jQuery $命名冲突解决方案汇总
2014/11/13 Javascript
浅谈javascript中字符串String与数组Array
2014/12/31 Javascript
jQuery使用$.get()方法从服务器文件载入数据实例
2015/03/25 Javascript
JS实现超精简响应鼠标显示二级菜单代码
2015/09/12 Javascript
jQuery实现简单的tab标签页效果
2016/09/12 Javascript
原生js实现电商侧边导航效果
2017/01/19 Javascript
微信小程序 页面跳转和数据传递实例详解
2017/01/19 Javascript
angularjs实现过滤并替换关键字小功能
2017/09/19 Javascript
详解如何理解vue的key属性
2019/04/14 Javascript
微信小程序实现搜索功能并跳转搜索结果页面
2019/05/18 Javascript
layui 弹出删除确认界面的实例
2019/09/06 Javascript
基于vue实现图片验证码倒计时60s功能
2019/12/10 Javascript
PHP 502bad gateway原因及解决方案
2020/11/13 Javascript
详解Python中DOM方法的动态性
2015/04/11 Python
Python生成MD5值的两种方法实例分析
2019/04/26 Python
python 列表中[ ]中冒号‘:’的作用
2019/04/30 Python
python 整数越界问题详解
2019/06/27 Python
Django 中自定义 Admin 样式与功能的实现方法
2019/07/04 Python
opencv3/C++实现视频背景去除建模(BSM)
2019/12/11 Python
django模板获取list中指定索引的值方式
2020/05/14 Python
python3.6使用SMTP协议发送邮件
2020/05/20 Python
django 获取字段最大值,最新的记录操作
2020/08/09 Python
python闭包与引用以及需要注意的陷阱
2020/09/18 Python
Python3+Appium安装及Appium模拟微信登录方法详解
2021/02/16 Python
安德玛比利时官网:Under Armour比利时
2019/08/28 全球购物
晨会主持词
2014/03/17 职场文书
倡议书范文大全
2015/04/28 职场文书