关于mysql优化部分,有很多网友说尽量避免使用is null, is not null,select * 等,会导致索引失效,性能降低?那是否一定收到影响呢?真的就不会使用索引了吗?

本文的测试数据库版本为5.7.18,不同版本得出的结果可能会有所不同:

本文测试的两张表数据如下:

CREATE TABLE `t_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) NOT NULL,
`age` int(11) DEFAULT NULL,
`sex` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; INSERT INTO `t_user` (`id`, `name`, `age`, `sex`) VALUES ('1', 'jemis', '20', '男');
INSERT INTO `t_user` (`id`, `name`, `age`, `sex`) VALUES ('2', 'fox', '20', '男');
INSERT INTO `t_user` (`id`, `name`, `age`, `sex`) VALUES ('3', 'tony', '20', '男'); CREATE UNIQUE INDEX indexName ON t_user(name(20));

  一、索引字段不能为空的情况下:

测试select *  结合is null 和 is not null :

可以得出:

EXPLAIN select * from t_user where `name` is not null; 不使用索引;
      EXPLAIN select * from t_user where `name` is null; 不使用索引;

查询索引字段的情况下:

有以上可以得出查询索引字段时:

EXPLAIN select name from t_user where `name` is not null; 使用索引

EXPLAIN select name from t_user where `name` is null; 不使用索引

select 索引字段加 非索引字段时:

  

可以得出:当select索引字段+其他字段时:

     EXPLAIN select name,age from t_user where `name` is not null; 不使用索引

    EXPLAIN select name,age from t_user where `name` is null; 不使用索引

    

由此可见,当索引字段不可以为null 时,只有使用is not null 并且返回的结果集中只包含索引字段时,才使用索引

二、当索引字段可以为null 时测试数据:

CREATE TABLE `t_user1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
`sex` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; INSERT INTO `springtest`.`t_user1` (`id`, `name`, `age`, `sex`) VALUES ('1', 'jemis', '20', '男');
INSERT INTO `springtest`.`t_user1` (`id`, `name`, `age`, `sex`) VALUES ('2', 'fox', '20', '男');
INSERT INTO `springtest`.`t_user1` (`id`, `name`, `age`, `sex`) VALUES ('3', 'tony', '20', '男'); CREATE UNIQUE INDEX indexName ON t_user1(name(20));

当索引字段可以为null,使用is null ,is not null:

当select * 时:

查询语句select *:EXPLAIN select * from t_user1 where `name` is not null;; 不使用索引
                 EXPLAIN select * from t_user1 where `name` is null; 使用索引

select 索引字段:

select 索引字段的结论为:

EXPLAIN select name from t_user1 where `name` is not null; 使用索引
            EXPLAIN select name from t_user1 where `name` is null; 使用索引

select 索引字段 + 非索引字段 为:

当select索引字段+其他字段时: EXPLAIN select name,age from t_user1 where `name` is not null;不使用索引,会导致索引失效
                                                    EXPLAIN select name,age from t_user1 where `name` is null; 使用索引

总结以上情形可知:1、当索引字段不可以为null 时,只有使用is not null 返回的结果集中只包含索引字段时,才使用索引

2、当索引字段可以为空时,使用 is null 不影响覆盖索引,但是使用 is not null 只有完全返回索引字段时才会使用索引

最后附上本文的测试完整版sql以及结论:

CREATE TABLE `t_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) NOT NULL,
`age` int(11) DEFAULT NULL,
`sex` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; INSERT INTO `springtest`.`t_user` (`id`, `name`, `age`, `sex`) VALUES ('', 'jemis', '', '男');
INSERT INTO `springtest`.`t_user` (`id`, `name`, `age`, `sex`) VALUES ('', 'fox', '', '男');
INSERT INTO `springtest`.`t_user` (`id`, `name`, `age`, `sex`) VALUES ('', 'tony', '', '男');
CREATE UNIQUE INDEX indexName ON t_user(name(20)); CREATE TABLE `t_user1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
`sex` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; INSERT INTO `springtest`.`t_user1` (`id`, `name`, `age`, `sex`) VALUES ('', 'jemis', '', '男');
INSERT INTO `springtest`.`t_user1` (`id`, `name`, `age`, `sex`) VALUES ('', 'fox', '', '男');
INSERT INTO `springtest`.`t_user1` (`id`, `name`, `age`, `sex`) VALUES ('', 'tony', '', '男'); CREATE UNIQUE INDEX indexName ON t_user1(name(20)); 当字段值可以为null,使用is null ,is not null,
查询语句:EXPLAIN select * from t_user1 where `name` is not null;; 不使用索引
EXPLAIN select * from t_user1 where `name` is null; 使用索引 当不使用select * 时 : EXPLAIN select name from t_user1 where `name` is not null; 使用索引
EXPLAIN select name from t_user1 where `name` is null; 使用索引 当select索引字段+其他字段时: EXPLAIN select name,age from t_user1 where `name` is not null;不使用索引,会导致索引失效
EXPLAIN select name,age from t_user1 where `name` is null; 使用索引 从以上可以看出,当索引字段可以为空时,使用 is null 不影响覆盖索引,但是使用 is not null 只有完全返回索引字段时才会使用索引 当字段值不能为null 时,EXPLAIN select * from t_user where `name` is not null; 不使用索引;
EXPLAIN select * from t_user where `name` is null; 不使用索引; 当select索引字段 时 : EXPLAIN select name from t_user where `name` is not null; 使用索引
EXPLAIN select name from t_user where `name` is null; 不使用索引 当select索引字段+其他字段时: EXPLAIN select name,age from t_user where `name` is not null; 不使用索引
EXPLAIN select name,age from t_user where `name` is null; 不使用索引 由此可见,当索引字段不可以为null 时,只有使用is not null 返回的结果集中只包含索引字段时,才使用索引

mysql 优化之 is null ,is not null 索引使用测试的更多相关文章

  1. mysql优化 | 存储引擎,建表,索引,sql的优化建议

    个人对于选择存储引擎,建表,建索引,sql优化的一些总结,给读者提供一些参考意见 推荐访问我的个人网站,排版更好看: https://chenmingyu.top/mysql-optimize/ 存储 ...

  2. 项目中常用的19条MySQL优化

    声明一下:下面的优化方案都是基于 " Mysql-索引-BTree类型 " 的 一.EXPLAIN 做MySQL优化,我们要善用 EXPLAIN 查看SQL执行计划. 下面来个简单 ...

  3. 19条MySQL优化准则

    1.EXPLAIN 做MySQL优化,我们要善用EXPLAIN查看SQL执行计划. 下面来个简单的示例,标注(1.2.3.4.5)我们要重点关注的数据: type列,连接类型.一个好的SQL语句至少要 ...

  4. 巧用这19条MySQL优化,效率至少提高3倍

    阅读本文大概需要 3.8 分钟. 作者丨喜欢拿铁的人 https://zhuanlan.zhihu.com/p/49888088 本文我们来谈谈项目中常用的MySQL优化方法,共19条,具体如下: 1 ...

  5. 项目中常用的MySQL 优化

    本文我们来谈谈项目中常用的MySQL优化方法,共19条,具体如下: 一.EXPLAIN 做MySQL优化,我们要善用EXPLAIN查看SQL执行计划. 下面来个简单的示例,标注(1.2.3.4.5)我 ...

  6. SQL学习笔记之项目中常用的19条MySQL优化

    在写文章之前,首先感谢 飞友科技 陆老师提供的文档.. 声明一下:下面的优化方案都是基于 “ Mysql-索引-BTree类型 ” 的 0x00 EXPLAIN 做MySQL优化,我们要善用 EXPL ...

  7. 项目中常用的MySQL优化方法--壹拾玖条

    1.EXPLAIN 做MySQL优化,我们要善用EXPLAIN查看SQL执行计划. 下面来个简单的示例,标注(1.2.3.4.5)我们要重点关注的数据: type列,连接类型.一个好的SQL语句至少要 ...

  8. 19条常用的MySQL优化方法(转)

    本文我们来谈谈项目中常用的MySQL优化方法,共19条,具体如下:1.EXPLAIN命令做MySQL优化,我们要善用EXPLAIN查看SQL执行计划.下面来个简单的示例,标注(1.2.3.4.5)我们 ...

  9. MySQL 效率提高N倍的19条MySQL优化秘籍

    一.EXPLAIN 做MySQL优化,我们要善用 EXPLAIN 查看SQL执行计划. 下面来个简单的示例,标注(1,2,3,4,5)我们要重点关注的数据 type列,连接类型.一个好的sql语句至少 ...

  10. 项目中常用的19条MySQL优化技巧

    原文:https://segmentfault.com/a/1190000012155267 声明一下:下面的优化方案都是基于 “ Mysql-索引-BTree类型 ” 的 一.EXPLAIN 做My ...

随机推荐

  1. getattribute方法,Python属性访问拦截器的用法

    __getattribute__()方法是属性访问时的拦截器,每当访问属性的时候,会先执行这个方法,然后再执行访问属性的操作步骤,可以用来记录属性访问的log.代码示例如下:   class Itca ...

  2. 20191214 Codeforces Round #606 (Div. 2, based on Technocup 2020 Elimination Round 4)

    概述 切了 ABCE,Room83 第一 还行吧 A - Happy Birthday, Polycarp! 题解 显然这样的数不会很多. 于是可以通过构造法,直接求出 \([1,10^9]\) 内所 ...

  3. lxml

    lxml导入 Element类 节点List相关操作 节点属性相关操作 节点文本相关操作 节点遍历相关操作 节点序列化 ElementTree类 解析文件和字符串 对象解析 增量解析 事件驱动解析 命 ...

  4. 订单结算submit_order.php扣库存,扣账号金额(学生笔记)

    <?php header("Content-type: text/html; charset=utf-8"); session_start(); include_once(& ...

  5. NSURLSession的文件上传

    文件上传的步骤: (1)确定上传路径 (2)创建“可变”请求对象 (3)修改请求方法为POST  --设置请求头信息,告诉服务器这是一个文件上传请求  --按照固定的格式拼接数据 (4)设置请求体信息 ...

  6. 一文解读MVC/MVP/MVVM (转)

    这篇文章对目前 GUI 应用中的 MVC.MVP 和 MVVM 架构模式进行详细地介绍. MVC 在整个 GUI 编程领域,MVC 已经拥有将近 50 年的历史了.早在几十年前,Smalltalk-7 ...

  7. ORACLE DATAGUARD 日志传输状态监控

    ORACLE DATAGUARD的主备库同步,主要是依靠日志传输到备库,备库应用日志或归档来实现.当主.备库间日志传输出现GAP,备库将不再与主库同步.因此需对日志传输状态进行监控,确保主.备库间日志 ...

  8. 获取格式字符串第idx个值及实例

    --根据索引idx值获取格式串中第idx个值 如数据'11,12,13,14,15,16' 方法:格式串+分隔符:@str='11,12,13,14,15,16'+',' select dbo.Get ...

  9. 小程序npm(初级篇)

    小程序npm NPM是随同NodeJS一起安装的包管理工具,能解决NodeJS代码部署上的很多问题,常见的使用场景有以下几种: 允许用户从NPM服务器下载别人编写的第三方包到本地使用. 允许用户从NP ...

  10. docker 私有registry harbor安装

    一,harbor安装: 参考:Installation and Configuration Guide 1,安装docker 2,安装docker compose sudo curl -L " ...