MySQL查询为什么没走索引?这篇文章带你全面解析
工作中,经常遇到这样的问题,我明明在MySQL表上面加了索引,为什么执行SQL查询的时候却没有用到索引?
同一条SQL有时候查询用到了索引,有时候却没用到索引,这是咋回事?
原因可能是索引失效了,失效的原因有以下几种,看你有没有踩过类似的坑?
1. 数据准备:
有这么一张用户表,在name字段上建个索引:
CREATE TABLE `user` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
`name` varchar(255) DEFAULT NULL COMMENT '姓名',
`age` int DEFAULT NULL COMMENT '年龄',
PRIMARY KEY (`id`),
KEY `idx_name` (`name`)
) ENGINE=InnoDB COMMENT='用户表';
2. Explain详解:
想要查看一条SQL是否用到索引?用到了哪种类型的索引?
可以使用explain关键字,查看SQL执行计划。例如:
explain select * from user where id=1;

可以看到type=const,表示使用了主键索引。
explain的所有type类型如下:

3. 失效原因
1. 数据类型隐式转换
name字段是varchar类型,如果我们使用数据类型查询,就会产生数据类型转换,虽然不会报错,但是无法用到索引。
explain select * from user where name='一灯';

explain select * from user where name=18;

2. 模糊查询 like 以%开头
explain select * from user where name like '张%';

explain select * from user where name like '%张';

3. or前后没有同时使用索引
虽然name字段上加了索引,但是age字段没有索引,使用or的时候会全表扫描。
# or前后没有同时使用索引,导致全表扫描
explain select * from user where name='一灯' or age=18;

4. 联合索引,没有使用第一列索引
如果我们在(name,age)上,建立联合索引,但是查询条件中只用到了age字段,也是无法用到索引的。
使用联合索引,必须遵循最左匹配原则,首先使用第一列字段,然后使用第二列字段。
CREATE TABLE `user` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
`name` varchar(255) DEFAULT NULL COMMENT '姓名',
`age` int DEFAULT NULL COMMENT '年龄',
PRIMARY KEY (`id`),
KEY `idx_name_age` (`name`,`age`)
) ENGINE=InnoDB COMMENT='用户表';

5. 在索引字段进行计算操作
如果我们在索引列进行了计算操作,也是无法用到索引的。
# 在主键索引上进行计算操作,导致全表扫描
explain select * from user where id+1=2;

6. 在索引字段字段上使用函数
如果我们在索引列使用函数,也是无法用到索引的。

7. 优化器选错索引
同一条SQL有时候查询用到了索引,有时候却没用到索引,这是咋回事?
这可能是优化器选择的结果,会根据表中数据量选择是否使用索引。

当表中大部分name都是一灯,这时候用name='一灯'做查询,还会不会用到索引呢?
索引优化器会认为,用索引还不如全表扫描来得快,干脆不用索引了。

当然我们认为优化器优化的不对,也可以使用force index强制使用索引。

知识点总结:

文章持续更新,可以微信搜一搜「 一灯架构 」第一时间阅读更多技术干货。
MySQL查询为什么没走索引?这篇文章带你全面解析的更多相关文章
- MySQL查询性能优化七种武器之索引下推
前面已经讲了MySQL的其他查询性能优化方式,没看过可以去了解一下: MySQL查询性能优化七种武器之索引潜水 MySQL查询性能优化七种武器之链路追踪 今天要讲的是MySQL的另一种查询性能优化方式 ...
- 两篇文章带你走入.NET Core 世界:Kestrel+Nginx+Supervisor 部署上云服务器(二)
背景: 上一篇:两篇文章带你走入.NET Core 世界:CentOS+Kestrel+Ngnix 虚拟机先走一遍(一) 已经交待了背景,这篇就省下背景了,这是第二篇文章了,看完就木有下篇了. 直接进 ...
- 两篇文章带你走入.NET Core 世界:CentOS+Kestrel+Ngnix 虚拟机先走一遍(一)
背景: 上一篇:ASP.Net Core on Linux (CentOS7)共享第三方依赖库部署 已经交待了背景,这篇就省下背景了. 折腾的过程分两步: 第一步是:本机跑虚拟机部署试一下: 第二步是 ...
- 三篇文章带你极速入门php(三)之php原生实现登陆注册
看下成果 ps:纯天然h5,绝不添加任何添加剂(css)以及化学成分(js)(<( ̄ ﹌  ̄)我就是喜欢纯天然,不接受任何反驳) 关于本文 用原生的php和html做了一个登陆注册,大概是可以窥 ...
- 难道你还不知道Spring之事务的回滚和提交的原理吗,这篇文章带你走进源码级别的解读。
上一篇文章讲解了获取事务,并通过获取的connection设置只读,隔离级别等:这篇文章讲事务剩下的回滚和提交. 事务的回滚处理 之前已经完成了目标方法运行前的事务准备工作.而这些准备工作的最大目的无 ...
- mysql left join查询没走索引
SELECT t0.ID as id, t0.`NAME` as name, t0.PHONE as phone, t0.`CITY_CODE` as cityCode, t0.SHOOTING_TI ...
- mysql 有索引没走索引 更新锁全表
Session 1: mysql> select connection_id(); +-----------------+ | connection_id() | +-------------- ...
- MySQL查询性能优化七种武器之索引潜水
有读者可能会一脸懵逼? 啥是索引潜水? 你给起的名字的吗?有没有索引蛙泳? 这个名字还真不是我起的,今天要讲的知识点就叫索引潜水(Index dive). 先要从一件怪事说起: 我先造点数据复现一下问 ...
- 主机名变成bogon?连不上mysql?你需要看下这篇文章
通过navicat for mysql操作部署在虚拟机centos里面的mysql数据库时候总是出现类似于下面的提示信息: Can't connct to MySQL server on '*.*.* ...
随机推荐
- JavaWeb和WebGIS学习笔记(六)——使用ArcGIS for Server发布地图服务
系列链接: Java web与web gis学习笔记(一)--Tomcat环境搭建 Java web与web gis学习笔记(二)--百度地图API调用 JavaWeb和WebGIS学习笔记(三)-- ...
- C#中检查null的语法糖
今天看到已经更新了devblogs,新增的C# 11的!!(用于检查null的语法)经过非常长的讨论,最后取消了.然后我又想起来null检查,这个可以说一说. 函数参数null检查 传统写法 写一个函 ...
- FreeRTOS --(7)任务管理之入门篇
转载自 https://blog.csdn.net/zhoutaopower/article/details/107019521 任务管理是操作系统中重中之重,不管什么 OS ,任务的调度管理都是核心 ...
- apparmor 源码分析
这里不对apparmor做介绍,记录一下源码分析过程. 初始化 static int __init apparmor_init(void) -> security_add_hooks(appar ...
- Windows常用cmd命令总结
cmd是command的缩写,即命令提示符. 运行操作: 使用"Win+R"快捷键召唤出运行窗口,再在运行中输入cmd即可. 1.ping 用法: 常用举例: ping www.g ...
- C++进阶-1-模板基础(函数模板、类模板)
C++进阶 模板 1.1 函数模板 1 #include<iostream> 2 using namespace std; 3 4 // 模板 5 6 // 模板的简单实例 7 // 要求 ...
- 一款高速的NET版的离线免费OCR
PaddleOCR.Onnx 一款基于Paddle的OCR,项目使用ONNX模型,速度更快.本项目同时支持X64和X86的CPU上使用.本项目是一个基于PaddleOCR的C++代码修改并封装的.NE ...
- git 撤销远程 commit
参考: https://blog.csdn.net/xs20691718/article/details/51901161 https://www.cnblogs.com/lfxiao/p/93787 ...
- JSON数据传输大法第一式——用OADate处理日期格式
JSON作为一种轻量级的数据交换格式,通常采用完全独立于编程语言的文本格式来存储和表示数据.它的层次结构简洁清晰,易于人们的阅读和编写,此外机器编写和生成也会变得容易,可以有效地提升网络传输效率,这些 ...
- c++ web框架实现之静态反射实现
0 前言 最近在写web框架,框架写好后,需要根据网络发来的请求,选择用户定义的servlet来处理请求.一个问题就是,我们框架写好后,是不知道用户定义了哪些处理请求的类的,怎么办? 在java里有一 ...