mysql中IS NULL、IS NOT NULL不能走索引?

不知道是啥原因也不知道啥时候, 江湖上流传着这么一个说法 mysql查询条件包含IS NULL、IS NOT NULL、!=、like %* 、like %*%, 不能 使用索引查询, 只能 使用全表扫描。

刚入行时我也是这么认为的,还奉为真理!

但是时间工作中你会发现还是走索引啊!下面我们来一一探究其中的奥秘。

一、首先验证一下是会走索引的

创建一个表,结构如下:

create table user_info( id int PRIMARY key auto_increment, name varchar(16) default '', age tinyint default 0, address varchar(32) default '', PRIMARY KEY (`id`), KEY `name` (`name`), KEY `address_2` (`address`,`name`) ); ALTER TABLE user_info ADD INDEX (NAME); ALTER TABLE user_info ADD INDEX (address);
数据1 INSERT INTO user_info(NAME,age,address) VALUES (9,9,'shenzhen9'); BEGIN DECLARE i INT DEFAULT 1000; WHILE i < 9000 DO INSERT INTO user_info (`NAME`, `age`, `address`) VALUES (NULL, i , SUBSTRING(MD5(RAND()),1,10) ) ; SET i = i+ 1 ; END WHILE ; ① EXPLAIN SELECT * FROM user_info WHERE `name` IS NOT NULL ② EXPLAIN SELECT * FROM user_info WHERE `name` !='9' ③ EXPLAIN SELECT * FROM user_info WHERE `name` is null
数据2 INSERT INTO user_info(NAME,age,address) VALUES (null,9,'shenzhen9'); BEGIN DECLARE i INT DEFAULT 1000; WHILE i < 9000 DO INSERT INTO user_info (`NAME`, `age`, `address`) VALUES (REPLACE(UUID(),'-',''), i , SUBSTRING(MD5(RAND()),1,10) ) ; SET i = i+ 1 ; END WHILE ; ④ EXPLAIN SELECT * FROM user_info WHERE `name` IS NOT NULL ⑤ EXPLAIN SELECT * FROM user_info WHERE `name` !='9' ⑥ EXPLAIN SELECT * FROM user_info WHERE `name` is null

执行数据1 会发现sql①②走索引,③不走索引

执行数据2 会发现sql⑥走索引,④⑤不走索引

二、B+树数据排列规则

1、聚簇索引索引:

①页面中的记录是按照主键值进行排序的;

②B+树每一层节点(页面)都是按照页中记录的主键值大小进行排序的;

③B+树叶子节点对应的页面中存储的是完整的用户记录(就是一条记录中包含我们定义的所有列值,还包含一些InnoDB自己添加的一些隐藏列);

2、二级索引:

①页面中的记录是按照给定的索引列的值进行排序的。

②B+树每一层节点(页面)都是按照页中记录的给定的索引列的值进行排序的。

③B+树叶子节点对应的页面中存储的只是索引列的值 + 主键值。

二级索引值能为空。那对于索引列值为NULL的二级索引记录,在B+树的哪个位置呢?

在B+树的最左边。如下图

至于为什么,InnoDB是这样的规定:SQL中的NULL值是列中最小的值

什么时候索引又不生效了呢?

对比数据1和数据2两个数据中null值的数量不一样,当null值占多数时is not null 和!=走索引 ,is null不走索引了,数据2刚好相反。

索引(二级索引)扫描成本:

1、读取索引记录成本

2、反查主键索引查找完整数据成本即回表

如果查询读取的二级索引越多那么需要回表查询的次数就会越多,达到一定的比例就会变成全部查询了,也就是上面null 查询时索引有时不生效的原因。

综上MySQL中决定使不使用某个索引执行查询的依据是成本大小。而不是在WHERE子句中用了IS NULL、IS NOT NULL、!=这些条件

三、如何让like‘%字符串%’,‘字符串%’时走索引

通常情况下我们使用like % %、% 的确不会走索引 但是并不代表就一定不能走索引,我们对上面表中name和age建立复合索引

explain select name from user_info where name like '%a%'; 1 SIMPLE user_info index idx_n_a 53 6 16.67 Using where; Using index explain select name,age from user_info where name like '%a%'; 1 SIMPLE user_info index idx_n_a 53 6 16.67 Using where; Using index 以下两个例子是查询了不在复合索引中的列进而造成全表扫描 explain select name,age,address from user_info where name like '%a%'; 1 SIMPLE user_info ALL 6 16.67 Using where explain select * from user_info where name like '%a%'; 1 SIMPLE user_info ALL 6 16.67 Using where

所以like走不走索引并不是绝对的,要看使用条件!

来源:https://www.tuicool.com/articles/ANnIFrF

欢迎关注微信公众号【慕容千语】

bcp 不能调用where 子句_技术分享 || Mysql中IS NULL、IS NOT NULL不能走索引?相关推荐

  1. mysql优化说出九条_技术分享 | MySQL 优化:为什么 SQL 走索引还那么慢?

    原标题:技术分享 | MySQL 优化:为什么 SQL 走索引还那么慢? 背景 2019-01-11 9:00-10:00 一个 MySQL 数据库把 CPU 打满了. 硬件配置:256G 内存,48 ...

  2. date转timestamp格式_技术分享 | MySQL:timestamp 时区转换导致 CPU %sy 高的问题

    作者:高鹏文章末尾有他著作的<深入理解 MySQL 主从原理 32 讲>,深入透彻理解 MySQL 主从,GTID 相关技术知识.本文为学习记录,可能有误请谅解. 本文建议PC端观看,效果 ...

  3. date转timestamp格式_技术分享 | MySQL:timestamp 时区转换导致 CPU %sys 高的问题

    作者:高鹏 文章末尾有他著作的<深入理解 MySQL 主从原理 32 讲>,深入透彻理解 MySQL 主从,GTID 相关技术知识. 本文为学习记录,可能有误请谅解. 本文建议PC端观看, ...

  4. 发布json数据_技术分享 | MySQL 8.0.17 GA 发布!

    昨日 MySQL 官网正式发布 8.0.17 / 5.7.27 / 5.6.45 三个(维护)版本,距离上一个 GA 版本(8.0.16)发布时隔仅 88 天! MySQL 各开发团队的博客网站,同一 ...

  5. mysql timestamp 当前_技术分享 | MySQL 复制那点事 - Seconds_behind_Master 参数调查笔记

    作者:戴骏贤 网易游戏 技术部资深数据库系统工程师. 本文来源:原创投稿 *爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源. 文章阅读时间约 15 分钟,文中著名参考文献在 ...

  6. mysql 走索引 很慢_技术分享 | MySQL优化:为什么SQL走索引还那么慢?

    作者:胡呈清 背景 2019-01-11 9:00-10:00 一个 MySQL 数据库把 CPU 打满了. 硬件配置:256G 内存,48 core 分析过程 接手这个问题时现场已经不在了,信息有限 ...

  7. 技术分享 | MySQL中MGR中SECONDARY节点磁盘满,导致mysqld进程被OOM Killed

    欢迎来到 GreatSQL社区分享的MySQL技术文章,如有疑问或想学习的内容,可以在下方评论区留言,看到后会进行解答 在MGR测试中,人为制造磁盘满问题后,节点被oom killed 问题描述 在对 ...

  8. 多少行数_技术分享 | MySQL:查询字段数量多少对查询效率的影响

    作者:高鹏 文章末尾有他著作的<深入理解 MySQL 主从原理 32 讲>,深入透彻理解 MySQL 主从,GTID 相关技术知识. 这个问题是最近一个朋友问我的.刚好就好好看了一下,留下 ...

  9. mysql 客户端_技术分享 | MySQL 客户端连不上(1045 错误)原因全解析

    作者:Carlos Tutte.Marcos Albe 翻译:管长龙 在我们学习 MySQL 或从事 MySQL DBA 工作期间,时常会遇到:"我尝试连接到 MySQL 并且收到1045 ...

最新文章

  1. [SDOI2009]晨跑
  2. 链表的基本操作(c++实现)
  3. linux文件的权限模式,Linux文件权限和访问模式
  4. 安装、启动、配置zookeeper(window版)
  5. typora打开pdf文件提示文件过大_Win7/Win10拷贝到U盘容量足够却提示文件过大的解决方法...
  6. python-类的基本知识
  7. 58同城 php,58同城PHP面试试题
  8. windows不能在本地启动OracleDBConsole
  9. 新手必看:揭秘德州扑克概率表
  10. 不使用border-radius,实现一个可复用的高度和宽度都自适应的圆角矩形
  11. python能做什么工作-Python学完工作不好找?看看数据分析可视化都可以做什么
  12. java中map的使用和排序使用
  13. LINUX下载编译zrtp
  14. vmware给linux虚拟机添加新的分区
  15. 深入理解LSTM神经网络
  16. RS232和RS485通讯接口的区别
  17. Golang优秀开源项目汇总, 10大流行Go语言开源项目, golang 开源项目全集(golang/go/wiki/Projects), GitHub上优秀的Go开源项目...
  18. 程序员的浪漫之——情侣日常小程序
  19. 腾讯云商用密码合规解决方案,亮相2021商用密码应用创新高端研讨会
  20. html项目符号正方形,HTML无序列表| HTML项目符号列表

热门文章

  1. 需要单机还是集群部署_单机、集群和分布式(微服务结构)的区别
  2. 圆弧半径计算图解_刀尖圆弧半径补偿G40,G41,G42 左补偿右补偿你真的能搞清楚吗...
  3. 结构化分析和面向对象分析的区别 例子_管理游戏测评例子
  4. python自动搜索请求失败_http请求 request失败自动重新尝试代码示例
  5. python excel 转json_Python办公自动化| word 表格转excel
  6. 重装谷歌浏览器chrome:未知错误导致安装失败
  7. matlab绘图白边设定
  8. Android之Bundle类
  9. Android之Activity框架
  10. 万字长文丨7个经典问题,助你拿下Java面试(建议收藏)