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 相关文章推荐
MySql存储过程之逻辑判断和条件控制
May 26 MySQL
解决Navicat for Mysql连接报错1251的问题(连接失败)
May 27 MySQL
MySQL5.7并行复制原理及实现
Jun 03 MySQL
MySQL中in和exists区别详解
Jun 03 MySQL
MySQL系列之九 mysql查询缓存及索引
Jul 02 MySQL
MySQL的全局锁和表级锁的具体使用
Aug 23 MySQL
MySQL表类型 存储引擎 的选择
Nov 11 MySQL
Mysql Innodb存储引擎之索引与算法
Feb 15 MySQL
MySQL日期时间函数知识汇总
Mar 17 MySQL
数据分析数据库ClickHouse在大数据领域应用实践
Apr 03 MySQL
MySQL数据库安装方法与图形化管理工具介绍
May 30 MySQL
浅谈MySql update会锁定哪些范围的数据
Jun 25 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
PHP性能分析工具xhprof的安装使用与注意事项
2017/12/19 PHP
Laravel使用scout集成elasticsearch做全文搜索的实现方法
2018/11/30 PHP
laravel框架创建授权策略实例分析
2019/11/22 PHP
PHP执行系统命令函数实例讲解
2021/03/03 PHP
javascript 清除输入框中的数据
2009/04/13 Javascript
Wordpress ThickBox 添加“查看原图”效果代码
2010/12/11 Javascript
基于jQuery的计算文本框字数的代码
2012/06/06 Javascript
Three.js源码阅读笔记(物体是如何组织的)
2012/12/27 Javascript
ExtJs设置GridPanel表格文本垂直居中示例
2013/07/15 Javascript
Node.js中使用事件发射器模式实现事件绑定详解
2014/08/15 Javascript
node.js中的dns.getServers方法使用说明
2014/12/08 Javascript
JS仿JQuery选择器功能
2017/03/08 Javascript
ES6新数据结构Set与WeakSet用法分析
2017/03/31 Javascript
angularJs复选框checkbox选中进行ng-show显示隐藏的方法
2018/10/08 Javascript
js+html5 canvas实现ps钢笔抠图
2019/04/28 Javascript
Vue的Options用法说明
2020/08/14 Javascript
vue3.0+vue-router+element-plus初实践
2020/12/02 Vue.js
[01:15:36]加油刀塔第二期网络版
2014/08/09 DOTA
[01:05:56]Liquid vs VP Supermajor决赛 BO 第二场 6.10
2018/07/04 DOTA
Python中的并发编程实例
2014/07/07 Python
Python验证码识别的方法
2015/07/10 Python
Python 数据结构之队列的实现
2017/01/22 Python
Python实现文件信息进行合并实例代码
2018/01/17 Python
Django中间件工作流程及写法实例代码
2018/02/06 Python
Python3视频转字符动画的实例代码
2019/08/29 Python
基于Python批量生成指定尺寸缩略图代码实例
2019/11/20 Python
Python Socketserver实现FTP文件上传下载代码实例
2020/03/27 Python
从python读取sql的实例方法
2020/07/21 Python
Pandas之缺失数据的实现
2021/01/06 Python
CSS3教程(7):CSS3嵌入字体
2009/04/02 HTML / CSS
香港迪士尼乐园酒店预订:Hong Kong Disneyland Hotels
2017/05/02 全球购物
高校学生干部的自我评价分享
2013/11/04 职场文书
大学总结自我鉴定
2014/01/18 职场文书
放飞中国梦演讲稿
2014/04/23 职场文书
高中运动会广播稿
2014/09/16 职场文书
继续教育心得体会(共6篇)
2016/01/19 职场文书