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 25 MySQL
Mysql数据库索引面试题(程序员基础技能)
May 31 MySQL
MySQL 如何设计统计数据表
Jun 15 MySQL
详解MySQL多版本并发控制机制(MVCC)源码
Jun 23 MySQL
mysql联合索引的使用规则
Jun 23 MySQL
MySQL 8.0 驱动与阿里druid版本兼容问题解决
Jul 01 MySQL
MySQL 用 limit 为什么会影响性能
Sep 15 MySQL
数据分析数据库ClickHouse在大数据领域应用实践
Apr 03 MySQL
MySQL数据库查询进阶之多表查询详解
Apr 08 MySQL
讲解MySQL增删改操作
May 06 MySQL
MySQL解决Navicat设置默认字符串时的报错问题
Jun 16 MySQL
MySQL数据库实验之 触发器和存储过程
Jun 21 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 类商品秒杀计时实现代码
2010/05/05 PHP
php中怎么搜索相关联数组键值及获取之
2013/10/17 PHP
php多文件上传下载示例分享
2014/02/20 PHP
php判断一个数组是否为有序的方法
2015/03/27 PHP
PHP如何通过传引用的思想实现无限分类(代码简单)
2015/10/13 PHP
提高代码性能技巧谈—以创建千行表格为例
2006/07/01 Javascript
JavaScript高级程序设计(第3版)学习笔记7 js函数(上)
2012/10/11 Javascript
关于jQuery对象数据缓存Cache原理以及jQuery.data详解
2013/04/07 Javascript
Javascript实现滑块滑动改变值的实现代码
2013/04/12 Javascript
javascript窗口宽高,鼠标位置,滚动高度(详细解析)
2013/11/18 Javascript
JQuery中extend使用介绍
2014/03/13 Javascript
NodeJS学习笔记之Connect中间件模块(一)
2015/01/27 NodeJs
分享一个自己写的简单的javascript分页组件
2015/02/15 Javascript
浅谈JavaScript异常处理语句
2015/06/26 Javascript
JavaScript实现iframe自动高度调整和不同主域名跨域
2016/02/27 Javascript
JS中setTimeout和setInterval的最大延时值详解
2017/02/13 Javascript
socket.io学习教程之基本应用(二)
2017/04/29 Javascript
Angularjs自定义指令实现分页插件(DEMO)
2017/09/16 Javascript
详解JSON Web Token 入门教程
2018/07/30 Javascript
如何用JS模拟实现数组的map方法
2020/07/30 Javascript
vue中template的三种写法示例
2020/10/21 Javascript
JS实现手风琴特效
2020/11/08 Javascript
python中as用法实例分析
2015/04/30 Python
使用python绘制常用的图表
2016/08/27 Python
python 美化输出信息的实例
2018/10/15 Python
对Pycharm创建py文件时自定义头部模板的方法详解
2019/02/12 Python
python Django的web开发实例(入门)
2019/07/31 Python
python迭代器常见用法实例分析
2019/11/22 Python
迪奥美国官网:Dior美国
2019/12/07 全球购物
TUMI香港官网:国际领先的行李箱、背囊品牌
2021/03/01 全球购物
车祸赔偿收入证明
2014/01/09 职场文书
优秀少先队大队辅导员事迹材料
2014/05/04 职场文书
公开承诺书格式
2014/05/21 职场文书
普通党员群众路线教育实践活动心得体会
2014/11/04 职场文书
银行稽核岗位职责
2015/04/13 职场文书
幼儿园小班工作总结2015
2015/04/25 职场文书