当前位置: 首页 > news >正文

Mysql杂志(三十)——索引失效情况

1. 不符合最左前缀原则

这个不用多说了吧,大家应该懂的都懂,但是还是在下面附上示范吧,最左前缀原则就是想使用某一个索引,必须要使用这个索引的最左测的一列,不管是否需要,如果不使用就Mysql的优化器就不会选择使用这个索引。

-- 创建索引:INDEX idx_name_age_gender(name, age, gender)-- 有效使用(符合最左前缀)
SELECT * FROM users WHERE name = '张三' AND age = 25;-- 失效情况:
SELECT * FROM users WHERE age = 25;              -- 跳过name列
SELECT * FROM users WHERE name = '张三' AND gender = 'M'; -- 跳过age列

2. 对索引列使用函数或计算

这个也很好理解,就是字面上的意思,如果对条件列使用了函数或者计算那就会对索引失效,因为索引是等值查询,如果对他进行计算或者使用函数,那就是会对所以的数据对应的列进行相应的处理,就不会使用到索引。

-- 失效案例:
SELECT * FROM users WHERE YEAR(create_time) = 2023;  -- 对索引列使用函数
SELECT * FROM products WHERE price + 100 > 2000;     -- 对索引列进行计算-- 优化方案:
SELECT * FROM users WHERE create_time BETWEEN '2023-01-01' AND '2023-12-31';
SELECT * FROM products WHERE price > 1900;

3.使用不等于(!=或<>)或NOT IN

这个也是很好理解的,刚刚上面有说到索引是一个等值查询,如果是不等于这种就会全部扫描一遍然后得到满足条件的列,记住索引喜好等于!讨厌不等于!

-- 失效案例:
SELECT * FROM orders WHERE status != 'completed';
SELECT * FROM customers WHERE id NOT IN (1, 2, 3);-- 部分优化方案:
SELECT * FROM orders WHERE status IN ('pending', 'processing');
SELECT * FROM customers WHERE id > 3;  -- 如果ID连续

4.LIKE 通配符开头

这个其实也是和刚刚说的索引喜好有关系,如果是模糊查询就会对每一条数据进行比对,从而得到所有满足条件的数据,毋庸置疑这肯定就是全表扫描,索引必然失效,但使用前缀匹配或者对varchar类型的数据列使用前缀索引或者全文索引就没有那么糟,不然Mysql也不会推出这两个索引,虽然主包日常开发没有使用到。

-- 失效案例:
SELECT * FROM products WHERE name LIKE '%手机%';  -- 前导通配符
SELECT * FROM products WHERE name LIKE '_苹果%';  -- 前导通配符-- 有效使用:
SELECT * FROM products WHERE name LIKE '苹果%';   -- 前缀匹配

5. 隐式类型转换

这个怎么说呢,我们写Java的时候好像也有这个隐式转换,比如我们字符串转数字,数字转字符串一样,Mysql同意也是支持的,但是这样会造成索引的失效,因为无法等值匹配,需要每一个条数据对应的索引列转化成对应的类型再进行比较,如下:

-- 失效案例(phone是varchar类型):
SELECT * FROM users WHERE phone = 13800138000;  -- 字符串转数字-- 正确写法:
SELECT * FROM users WHERE phone = '13800138000';

这个phone是一个varchar类型,那么每一条数据的phone列都会先转数字对比,那么不就是全扫描了。而且这种类型转化查询出来的数据也不一定正确,因为涉及到精度的问题还有编码规则(如UTF—8)的影响。

6.OR 连接非索引列

这个其实也很好理解,我们InooDB的索引都是先对比第一索引列,即使想对比第二索引列也是在第一索引列成功命中的时候才会对比第二索引列,所以我们日常使用的时候如果有OR的场景尽量还是使用UNION进行数据集合合并,不然可能降低SQL性能。

-- 失效案例(age有索引,address无索引):
SELECT * FROM users WHERE age = 25 OR address = '北京';-- 优化方案:
SELECT * FROM users WHERE age = 25 
UNION
SELECT * FROM users WHERE address = '北京';-- 不会失效(会被优化器优化成in):
SELECT * FROM users WHERE age = 25 OR age = 26
-- 优化后:
SELECT * FROM users WHERE age in (25,26)-- 复合索引,可能会使用到部分索引(age)不会使用到(address):
CREATE INDEX idx_age_address ON users(age, address);
SELECT * FROM users WHERE age = 25 OR address = '北京';

7.个人认为不会索引失效的情况

1.范围查询>,<

主包个人认为是不会,因为我们InnoDB的索引都是B+树的格式,复合索引都遵守最左侧索引列 排序后再到第二列索引列排序,所以第一索引列相同的情况下,第二索引一点也是升序排序的,而且目录节点存的也是第一索引列和对应叶子节点指针,所以都是先按照第一索引找到满足条件的最左侧目录节点的行数据,然后顺序加载叶子节点对比每一条行数据第二索引是否满足。

网上说会造成索引失效或者部分索引失效的原因有的说是数据库不支持,有点说只会使用到第一索引,但是主包认为,没有使用到索引的情况可能和Myslq的优化器有关,Mysql优化器只会选择执行成本最低的,然后索引建的有问题导致成本增加,那么Mysql就不会使用这个索引。当然这个是主包个人认为哈。

2.Select * 索引失效

其实主包个人认为不存在这个失效,因为我们的聚簇索引是根据主键来的,假如你查name,那么没有这个了列的索引,怎么能被称为索引失效呢?没用到聚簇索引吗?但本来就不现实好吧。如果加了name这一列的索引,那么select * 还要回表也就是查聚簇索引找多数据,那么这也叫索引失效吗?主包认为也不是。

MySQL 四种 EXPLAIN 命令对比分析

这里再对前两篇的内容进行一个补充吧,执行计划有四种格式我们已经说了2种了,其实后面的2种字段名都是相同的,所以就不冗余的去锁了,这边就给个表格大家看看吧。这个是基本功能的对比:

命令类型

输出格式

版本要求

是否执行查询

主要用途

EXPLAIN

表格格式

全版本

基础执行计划分析

EXPLAIN FORMAT=JSON

JSON格式

5.6+

详细执行计划分析

EXPLAIN FORMAT=TREE

树形结构

8.0+

可视化执行流程

EXPLAIN ANALYZE

表格+实际数据

8.0.18+

真实执行统计

这个是详细功能的对比:

对比维度

EXPLAIN

EXPLAIN FORMAT=JSON

EXPLAIN FORMAT=TREE

EXPLAIN ANALYZE

输出内容

基础执行计划

详细执行计划+成本估算

执行流程树形图

实际执行统计

执行成本

预估成本

预估成本

预估成本

实际成本

扫描行数

预估行数

预估行数

预估行数

实际行数

索引信息

基础索引使用

详细索引使用情况

索引使用路径

实际索引效率

是否执行查询

适用场景

快速检查

深度分析

流程可视化

精准优化

这个是优缺点分析:

命令类型

优点

缺点

最佳使用场景

EXPLAIN

简单直观,全版本支持

信息有限,只有预估数据

日常快速检查

EXPLAIN FORMAT=JSON

信息全面,可编程解析

输出冗长,需解析工具

自动化分析系统

EXPLAIN FORMAT=TREE

直观展示执行流程

缺少详细成本数据

复杂查询理解

EXPLAIN ANALYZE

真实执行数据,精准

会实际执行查询,有性能影响

生产环境精准调优

总结

本篇主要讲的就是Mysql索引失效的几种情况,以及对前两篇执行计划的补充。

http://www.dtcms.com/a/466051.html

相关文章:

  • 百度企业网站建设wordpress 数据库设计
  • 10.程序地址空间_1
  • 6.0 Labview中的类面向对象编程-类的使用(OOP)
  • 上海精品网站建设想设计一个公司的网站
  • 【计算机】常见的缓存和查看方法
  • Linux 进程间通信机制详解
  • 低轨卫星光模块控制中的MCU芯片抗辐照性能研究
  • 网站建设faq男人和女人做哪个网站
  • 网站优化排名易下拉系统如何让网站自适应
  • CTF攻防世界WEB精选基础入门:xff_referer
  • 做presentation的网站wordpress搜索框去掉
  • 原型设计、UI设计、前端页面和后台管理页面之间的关系解析
  • Linux的设备驱动模型
  • 鸿蒙NEXT USB服务开发:从基础概念到实战应用
  • 神华集团 两学一做 网站做金融量化的网站
  • 深圳拼团网站建设徐州网站建设报价
  • cpp-httplb库使用手册
  • TextureStreaming针对不同分档机型一般怎么设置
  • 自己做网站2008R2好还是win7qq推广
  • 快速上手!如何用GEO优化让品牌在AI搜索中脱颖而出
  • 道可云人工智能每日资讯|2025世界智能网联汽车大会将在北京举办
  • 【2025最新】【win10】vs2026+qt6.9+opencv(cmake编译opencv_contrib拓展模
  • 惠州做网站电话网站转移后后台无法登陆
  • 学习软件开发的网站公众号软文推广
  • 网站页面大小优化怎么做泉州网站制作哪个好微
  • 代理服务器ip免费邹平县seo网页优化外包
  • 深度学习基础-Chapter 01-感知机和全连接
  • 企业内部网站模板下载网站如何做ICP备案
  • 用js获取浏览器视口高度,并设置元素满屏显示
  • 南山网站建设哪家好静宁县建设局网站