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
MySQL sql_mode修改不生效的原因及解决
May 07 MySQL
Mysql官方性能测试工具mysqlslap的使用简介
May 21 MySQL
MySQL 使用事件(Events)完成计划任务
May 24 MySQL
MYSQL(电话号码,身份证)数据脱敏的实现
May 28 MySQL
浅谈mysql返回Boolean类型的几种情况
Jun 04 MySQL
mysql 直接拷贝data 目录下文件还原数据的实现
Jul 25 MySQL
MySQL之MyISAM存储引擎的非聚簇索引详解
Mar 03 MySQL
MySQL读取JSON转换的方式
Mar 18 MySQL
MySQL中rank() over、dense_rank() over、row_number() over用法介绍
Mar 23 MySQL
排查MySQL生产环境索引没有效果
Apr 11 MySQL
mysql数据库实现设置字段长度
Jun 10 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 常见郁闷问题答解
2006/11/25 PHP
利用Ffmpeg获得flv视频缩略图和视频时间的代码
2011/09/15 PHP
destoon实现公司新闻详细页添加评论功能的方法
2014/07/15 PHP
取得单条网站评论以数组形式进行输出
2014/07/28 PHP
PHP中file_get_contents函数抓取https地址出错的解决方法(两种方法)
2015/09/22 PHP
PHP表单提交后引号前自动加反斜杠的原因及三种办法关闭php魔术引号
2015/09/30 PHP
PHP中Socket连接及读写数据超时问题分析
2016/07/19 PHP
Laravel实现autoload方法详解
2017/05/07 PHP
ThinkPHP 3.2.3实现页面静态化功能的方法详解
2017/08/03 PHP
php注册系统和使用Xajax即时验证用户名是否被占用
2017/08/31 PHP
Javascript 遮罩层和加载效果代码
2013/08/01 Javascript
jQuery常用操作方法及常用函数总结
2014/06/19 Javascript
jQuery内置的AJAX功能和JSON的使用实例
2014/07/27 Javascript
基于Jquery实现焦点图淡出淡入效果
2015/11/30 Javascript
原生js实现焦点轮播图效果
2017/01/12 Javascript
JavaScript中使用webuploader实现上传视频功能(demo)
2017/04/10 Javascript
jquery使用iscorll实现上拉、下拉加载刷新
2017/10/26 jQuery
详解javascript appendChild()的完整功能
2018/08/18 Javascript
JS实现点击下拉列表文本框中出现对应的网址,点击跳转按钮实现跳转
2019/11/25 Javascript
关于AngularJS中几种Providers的区别总结
2020/05/17 Javascript
JavaScript中作用域链的概念及用途讲解
2020/08/06 Javascript
从零学Python之引用和类属性的初步理解
2014/05/15 Python
简单介绍Python的轻便web框架Bottle
2015/04/08 Python
我就是这样学习Python中的列表
2019/06/02 Python
基于 Django 的手机管理系统实现过程详解
2019/08/16 Python
python获取全国城市pm2.5、臭氧等空气质量过程解析
2019/10/12 Python
Python类的绑定方法和非绑定方法实例解析
2020/03/04 Python
浅谈keras2 predict和fit_generator的坑
2020/06/17 Python
通过实例了解python__slots__使用方法
2020/09/14 Python
思想作风建设心得体会
2014/10/22 职场文书
2014年单位工作总结范文
2014/11/27 职场文书
谢师宴答谢词
2015/01/05 职场文书
六一儿童节新闻稿
2015/07/17 职场文书
小米11和iphone12哪个值得买?小米11对比iphone12评测
2021/04/21 数码科技
JS前端监控采集用户行为的N种姿势
2022/07/23 Javascript
Python中np.random.randint()参数详解及用法实例
2022/09/23 Python