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部分操作
Apr 05 MySQL
教你用eclipse连接mysql数据库
Apr 22 MySQL
MySQL官方导出工具mysqlpump的使用
May 21 MySQL
解决mysql问题:由于找不到MSVCR120.dll,无法继续执行代码
Jun 26 MySQL
MySQL系列之三 基础篇
Jul 02 MySQL
浅谈MySQL之select优化方案
Aug 07 MySQL
浅谈MySQL表空间回收的正确姿势
Oct 05 MySQL
MySQL数据库中varchar类型的数字比较大小的方法
Nov 17 MySQL
MySql分区类型及创建分区的方法
Apr 13 MySQL
MySql数据库 查询时间序列间隔
May 11 MySQL
MySQL池化框架学习接池自定义
Jul 23 MySQL
Mysql中mvcc各场景理解应用
Aug 05 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
Mysql和网页显示乱码解决方法集锦
2008/03/27 PHP
php+mysqli预处理技术实现添加、修改及删除多条数据的方法
2015/01/30 PHP
浅谈json_encode用法
2015/03/05 PHP
ThinkPHP模板Volist标签嵌套循环输出多维数组的方法
2016/03/23 PHP
php中yar框架实例用法讲解
2020/12/27 PHP
javascript 简练的几个函数
2009/08/29 Javascript
风吟的小型JavaScirpt库 (FY.JS).
2010/03/09 Javascript
javascript实现页面内关键词高亮显示代码
2014/04/03 Javascript
关于javaScript注册click事件传递参数的不成功问题
2014/07/18 Javascript
javascript实现tab切换的两个实例
2015/11/05 Javascript
jQuery插件开发汇总
2016/05/15 Javascript
js微信分享API
2020/10/11 Javascript
如何解决IONIC页面底部被遮住无法向上滚动问题
2016/09/06 Javascript
javascript replace()第二个参数为函数时的参数用法
2016/12/26 Javascript
基于Vue实例对象的数据选项
2017/08/09 Javascript
9种python web 程序的部署方式小结
2014/06/30 Python
分析用Python脚本关闭文件操作的机制
2015/06/28 Python
实例Python处理XML文件的方法
2015/08/31 Python
Python的条件语句与运算符优先级详解
2015/10/13 Python
python检测文件夹变化,并拷贝有更新的文件到对应目录的方法
2018/10/17 Python
python利用Opencv实现人脸识别功能
2019/04/25 Python
使用python的pandas为你的股票绘制趋势图
2019/06/26 Python
python文件绝对路径写法介绍(windows)
2019/12/25 Python
Django 项目布局方法(值得推荐)
2020/03/22 Python
Numpy(Pandas)删除全为零的列的方法
2020/09/11 Python
css3类选择器之结合元素选择器和多类选择器用法
2017/03/09 HTML / CSS
德购商城:德国进口直邮商城
2017/06/13 全球购物
印尼极简主义和实惠的在线家具店:Fabelio
2019/03/27 全球购物
size?爱尔兰官方网站:英国伦敦的球鞋精品店
2019/03/31 全球购物
体育教师自我鉴定
2014/02/12 职场文书
公司合作意向书范文
2014/07/30 职场文书
男性健康日的活动方案
2014/08/18 职场文书
Python基于Opencv识别两张相似图片
2021/04/25 Python
uwsgi+nginx代理Django无法访问静态资源的解决
2021/05/10 Servers
Python激活Anaconda环境变量的详细步骤
2021/06/08 Python
大型强子对撞机再次重启探索“第五种自然力”
2022/04/29 数码科技