MySQL索引失效十种场景与优化方案


Posted in MySQL onMay 08, 2023
目录

1 数据准备

1.1 新建数据表

CREATE TABLE `player` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `player_id` varchar(256) NOT NULL COMMENT '运动员编号',
  `player_name` varchar(256) NOT NULL COMMENT '运动员名称',
  `height` int(11) NOT NULL COMMENT '身高',
  `weight` int(11) NOT NULL COMMENT '体重',
  `type` varchar(256) DEFAULT '0' COMMENT '球员类型',
  `game_performance` text COMMENT '最近一场比赛表现',
  PRIMARY KEY (`id`),
  KEY `idx_name_height_weight` (`player_name`,`height`,`weight`),
  KEY `idx_type` (`type`),
  KEY `idx_height` (`height`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8

以上数据表声明三个索引:

  • 联合索引:idx_name_height_weight
  • 普通索引:idx_type
  • 普通索引:idx_height

1.2 新增100万条数据

@SpringBootTest(classes = TestApplication.class)
@RunWith(SpringJUnit4ClassRunner.class)
public class PlayerServiceTest {

    @Resource
    private PlayerRepository playerRepository;

    @Test
    public void initBigData() {
        for (int i = 0; i < 1000000; i++) {
            PlayerEntity entity = new PlayerEntity();
            entity.setPlayerId(UUID.randomUUID().toString());
            entity.setPlayerName("球员_" + System.currentTimeMillis());
            entity.setType("0");
            entity.setWeight(150);
            entity.setHeight(188);
            entity.setGamePerformance("{\"runDistance\":8900.0,\"passSuccess\":80.12,\"scoreNum\":3}");
            playerRepository.insert(entity);
        }
    }
}

2 基础知识

2.1 explain type

执行计划中访问类型是重要分析指标:

MySQL索引失效十种场景与优化方案

2.2 explain Extra

Extra表示执行计划扩展信息:

MySQL索引失效十种场景与优化方案

3 索引失效场景

本章节介绍索引失效十种场景:

  • 查询类型错误
  • 索引列参与运算
  • 错误使用通配符
  • 未用到覆盖索引
  • OR连接无索引字段
  • MySQL放弃使用索引
  • 联合索引失效
    • 索引不完整
    • 索引中断
    • 非等值匹配
    • 最左索引缺失

3.1 查询类型错误

3.1.1 失效场景

explain select * from player where type = 0

MySQL索引失效十种场景与优化方案

3.1.2 解决方案

数据表定义type字段为varchar类型,查询必须使用相同类型:

MySQL索引失效十种场景与优化方案

3.2 索引列参与运算

3.2.1 失效场景

explain select * from player where height + 1 > 189

MySQL索引失效十种场景与优化方案

3.2.2 解决方案

explain select * from player where height > 188

MySQL索引失效十种场景与优化方案

3.3 MySQL放弃使用索引

3.3.1 失效场景

MySQL发现如果使用索引性能低于全表扫描则放弃使用索引。例如在表中100万条数据height字段值全部是188,所以执行如下语句时放弃使用索引:

explain select * from player where height > 187

MySQL索引失效十种场景与优化方案

3.3.2 解决方案一

调整查询条件值:

explain select * from player where height > 188

MySQL索引失效十种场景与优化方案

3.3.3 解决方案二

强制指定索引,这种方法不一定可以提升性能:

MySQL索引失效十种场景与优化方案

3.4 错误使用通配符

3.4.1 数据准备

避免出现3.3章节失效问题此处修改一条数据:

update player set player_name = '测试球员' where id = 1

3.4.2 失效场景一

explain select * from player where player_name like '%测试'

MySQL索引失效十种场景与优化方案

3.4.3 失效场景二

explain select * from player where player_name like '%测试%'

MySQL索引失效十种场景与优化方案

3.4.4 解决方案

explain select * from player where player_name like '测试%'

MySQL索引失效十种场景与优化方案

3.5 OR连接无索引字段

3.5.1 失效场景

type有索引,weight无索引:

explain select * from player where type = '0' or weight = 150

MySQL索引失效十种场景与优化方案

3.5.2 解决方案

weight新增索引,union拼装查询数据

explain
select * from player where type = '0' 
union
select * from player where weight = 150

MySQL索引失效十种场景与优化方案

3.6 未用到覆盖索引

3.6.1 失效场景

Using index condition表示使用索引,但是需要回表查询

explain select * from player where player_name like '测试%'

MySQL索引失效十种场景与优化方案

3.6.2 解决方案

覆盖索引含义是查询时索引列完全包含查询列,查询过程无须回表(需要在同一棵索引树)性能得到提升。Using Index; Using where表示使用覆盖索引并且用where过滤查询结果:

explain select id,player_name,height,weight from player where player_name like '测试%'

MySQL索引失效十种场景与优化方案

3.7 联合索引失效

3.7.1 完整使用

联合索引idx_name_height_weight完整使用key_len=778:

explain select * from player where player_name = '球员_1682577684751' and height = 188 and weight = 150

MySQL索引失效十种场景与优化方案

3.7.2 失效场景一:索引不完整

weight不在查询条件,所以只用到idx_name_height,所以key_len= 774:

explain select * from player where player_name = '球员_1682577684751' and height = 188

MySQL索引失效十种场景与优化方案

3.7.3 失效场景二:索引中断

height不在查询条件,所以只用到idx_name,所以key_len= 770:

explain select * from player where player_name = '球员_1682577684751' and weight = 150

MySQL索引失效十种场景与优化方案

3.7.4 失效场景三:非等值匹配

height非等值匹配,所以只用到idx_name_height,所以key_length=774:

explain select * from player where player_name='球员_1682577684751' and height > 188 and weight = 150

MySQL索引失效十种场景与优化方案

3.7.5 失效场景四:最左索引缺失

player_name最左索引不在查询条件,全表扫描

explain select * from player where weight = 150

MySQL索引失效十种场景与优化方案

4 文章总结

本文第一进行测试数据准备,第二介绍执行计划相关知识,第三介绍索引失效10种场景:查询类型错误,索引列参与运算,错误使用通配符,未用到覆盖索引,OR连接无索引字段,MySQL放弃使用索引,联合索引中索引不完整,索引中断,非等值匹配,最左索引缺失。

以上就是MySQL索引失效十种场景与优化方案的详细内容,更多关于MySQL索引失效的资料请关注三水点靠木其它相关文章!

MySQL 相关文章推荐
Idea连接MySQL数据库出现中文乱码的问题
Apr 14 MySQL
详解MySQL 联合查询优化机制
May 10 MySQL
一文读懂navicat for mysql基础知识
May 31 MySQL
如何搭建 MySQL 高可用高性能集群
Jun 21 MySQL
Prometheus 监控MySQL使用grafana展示
Aug 30 MySQL
MySQL中B树索引和B+树索引的区别详解
Mar 03 MySQL
MySQL读取JSON转换的方式
Mar 18 MySQL
MySQL RC事务隔离的实现
Mar 31 MySQL
MySQL批量更新不同表中的数据
May 11 MySQL
MySQL聚簇索引和非聚簇索引的区别详情
Jun 14 MySQL
MySQL远程无法连接的一些常见原因总结
Sep 23 MySQL
Mysql的Table doesn't exist问题及解决
Dec 24 MySQL
MySQL中的 inner join 和 left join的区别解析(小结果集驱动大结果集)
详解MySQL的内连接和外连接
May 08 #MySQL
关于MySQL中explain工具的使用
May 08 #MySQL
postgresql如何找到表中重复数据的行并删除
May 08 #MySQL
SQL Server数据库的三种创建方法汇总
May 08 #MySQL
SQL中去除重复数据的几种方法汇总(窗口函数对数据去重)
May 08 #MySQL
MySQL中TIMESTAMP类型返回日期时间数据中带有T的解决
Dec 24 #MySQL
You might like
Codeigniter上传图片出现“You did not select a file to upload”错误解决办法
2014/06/12 PHP
php判断两个日期之间相差多少个月份的方法
2015/06/18 PHP
Yii2处理密码加密及验证的方法
2019/05/12 PHP
Laravel修改验证提示信息为中文的示例
2019/10/23 PHP
js确定对象类型方法
2012/03/30 Javascript
jquery实现的导航固定效果
2014/04/28 Javascript
jquery中change()用法实例分析
2015/02/06 Javascript
jQuery实现带遮罩层效果的blockUI弹出层示例【附demo源码下载】
2016/09/14 Javascript
微信 java 实现js-sdk 图片上传下载完整流程
2016/10/21 Javascript
vue项目打包部署到服务器的方法示例
2018/08/27 Javascript
详解webpack自定义loader初探
2018/08/29 Javascript
微信小程序登录数据解密及状态维持实例详解
2019/05/06 Javascript
微信小程序防止多次点击跳转(函数节流)
2019/09/19 Javascript
基于vue和websocket的多人在线聊天室
2020/02/01 Javascript
Python的Django框架中的数据库配置指南
2015/07/17 Python
实例分析python3实现并发访问水平切分表
2018/09/29 Python
Python随机生成身份证号码及校验功能
2018/12/04 Python
Python如何爬取实时变化的WebSocket数据的方法
2019/03/09 Python
python 对一幅灰度图像进行直方图均衡化
2020/10/27 Python
Python爬虫进阶之爬取某视频并下载的实现
2020/12/08 Python
为你的html5网页添加音效示例
2014/04/03 HTML / CSS
玩具反斗城美国官网:Toys"R"Us
2016/09/17 全球购物
美国领先的男士和女士内衣购物网站:Freshpair
2019/02/25 全球购物
秘书专业自荐信范文
2013/12/26 职场文书
党的群众路线教育实践活动心得体会
2014/03/03 职场文书
《金孔雀轻轻跳》教学反思
2014/04/20 职场文书
学生上课看漫画的检讨书
2014/09/26 职场文书
领导干部作风整顿剖析材料
2014/10/11 职场文书
新教师个人工作总结
2015/02/06 职场文书
开场白怎么写
2015/06/01 职场文书
大学生安全教育心得体会
2016/01/15 职场文书
《窃读记》教学反思
2016/02/18 职场文书
2019秋季运动会口号
2019/06/25 职场文书
python实现局部图像放大
2021/11/17 Python
十大必看国产动漫排名,魁拔上线,第二曾在日本播出
2022/03/18 国漫
Win11局域网共享权限在哪里设置? Win11高级共享的设置技巧
2022/04/05 数码科技