一次线上SQL查询的索引失效问题排查过程,阿里P7看了也直呼内行

MySQL性能优化MySQL索引失效的13种隐蔽场景排查及解决方法 通过以上隐蔽场景的分析,我们可以看到 MySQL 索引失效的原因多种多样。在实际应用中,我们需要仔细分析查询语句,确保索引被正确使用。通过合理创建索引、优化查询语句和使用 EXPLAIN 命令分析查询计划,可以有效避免索引失效,提高数据库的性能。希望本文的内容对你有所帮助,如果你有任何问题或建议,欢迎在评论区留言。 阅读详情

前言

索引是MySQL中提高查询的有效手段,但是索引失效的问题就让开发同学们头大!这不少侠前段时间就亲身经历了这一让人掉发的问题。

业务场景

业务场景也不复杂,就是有两张表:用户表和用户积分表,现在想通过连接查询查出某一用户详细信息。话不多说,先给大家展示一下表结构:
在这里插入图片描述
可以看到,两张表的结构十分简单,而查询语句也仅仅是个平淡无奇的连接查询:

select * from cps_user_info ui inner join cps_user_score us on ui.user_id=us.user_id where us.id=1;

问题排查

建立索引有个原则是:连接查询的连接字段必须要有索引,这里没问题,并且主键也有索引。一切看上去都是那么的合规合法。但就是这条合法的SQL线上查询的时间将近8秒的开销(cps_user_score数据量数百万)!于是你着急忙慌的打开执行计划:

explain select * from cps_user_info ui inner join cps_user_score us on ui.user_id=us.user_id where us.id=1;

在这里插入图片描述
看看上图执行计划结果中cps_user_info表的type字段:ALL,糟糕,是心动的感觉,哦不,是心跳的感觉!怎么回事,于是你立马回头查看索引的创建,索引失效的条件,但是好像一切都很正常,难道是MySQL出了问题?这位同志,请保持理智。
在这里插入图片描述

于是我们做了尝试,将内连接查询换成左连接、右连接,然而并没有什么用。这个时候少侠有点慌了,情急之下想到查询表创建的语句,于是又是一顿操作猛如虎,一看战绩零比五。
在这里插入图片描述
但是这个建表语句看着也是正常啊,这索引的创建一看就是出自大师之手!嗯?等等,这里好像有一丢丢不一样,两张表的字符集CHARSET不同。难道是这个原因,抱着疑问,少侠修改了表的字符集(该操作线上环境慎重操作,万一出了问题可别大骂少侠这个渣男欺骗读者)。
修改完字符集之后再查询一次执行计划:
在这里插入图片描述
看看此时的cps_user_info的type是ref,显然这个时候走了索引。索引显然是两张表的字符集不同的原因导致的!那么深层次的原因是啥呢?其实深究原因的话,这个就是避免索引失效的一个重要原则:索引列不要参与计算!字符集不同的话,两张表连接查询,列的值必然是有转换计算的过程的。

扩展

其实如果知道explain extended+show warnings 组合命令的话,也是有助于快速定位问题的,将表的字符集改回utf8再通过组合命令查看:

mysql> explain extended select * from cps_user_info ui inner join cps_user_score us on ui.user_id=us.user_id where us.id=1;
+----+-------------+-------+------------+-------+-----------------+---------+---------+-------+------+----------+-------------+
| id | select_type | table | partitions | type  | possible_keys   | key     | key_len | ref   | rows | filtered | Extra       |
+----+-------------+-------+------------+-------+-----------------+---------+---------+-------+------+----------+-------------+
|  1 | SIMPLE      | us    | NULL       | const | PRIMARY,idx_uid | PRIMARY | 4       | const |    1 |   100.00 | NULL        |
|  1 | SIMPLE      | ui    | NULL       | ALL   | NULL            | NULL    | NULL    | NULL  |    1 |   100.00 | Using where |
+----+-------------+-------+------------+-------+-----------------+---------+---------+-------+------+----------+-------------+
2 rows in set, 2 warnings (0.01 sec)

mysql> show warnings;
+---------+------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Level   | Code | Message                                                                                                                                                                                                                                                                                                                             |
+---------+------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Warning | 1681 | 'EXTENDED' is deprecated and will be removed in a future release.                                                                                                                                                                                                                                                                   |
| Note    | 1003 | /* select#1 */ select `studying`.`ui`.`id` AS `id`,`studying`.`ui`.`user_id` AS `user_id`,`studying`.`ui`.`user_name` AS `user_name`,'1' AS `id`,'001' AS `user_id`,'6.80' AS `score` from `studying`.`cps_user_info` `ui` join `studying`.`cps_user_score` `us` where ((convert(`studying`.`ui`.`user_id` using utf8mb4) = '001')) |
+---------+------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

注意看convert(studying.ui.user_id using utf8mb4)这部分,显然这里是参与了运算的,这势必导致索引失效!

思考

其实本文涉及的索引失效仅仅就是索引列参与了运算导致的,但并不是显式的数学计算,实际上在开发中也会遇到各种各样的场景,深入理论并能识别理论在不同场景中的实际应用至关重要,谨以此与诸君共勉!
最后附上SQL创建的语句,以供感兴趣的读者实践。

CREATE TABLE `cps_user_info`(
	`id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` varchar(64) NOT NULL,
  `user_name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_uid`(`user_id`) USING BTREE
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
  
  CREATE TABLE `cps_user_score`(
	`id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` varchar(64) NOT NULL,
  `score` decimal(8,2) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_uid`(`user_id`) USING BTREE
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;```

索引失效原因 索引失效原因一.准备工作创建student表,id是主键 创建复合索引create index idx_name_age on student(name,age);查看索引show index from student;二.索引失效原因1.全值匹配我最爱explain select * from student where name = '张三' and age = 1;2.最佳左前缀法则,带 阅读详情

相关推荐

【索引失效如何排查】

10、 索引列使用了隐式类型转换:当查询语句中的查询条件与索引列类型不一致时,数据库会自动进行类型转换。9、 索引列被过度使用:当索引列被过度使用时,可能会导致索引失效。6、 检查数据库的配置和性能:如果数据库的配置和性能不足,可能会导致索引失效,因为查询可能需要很长时间才能完成。4、 检查索引列的选择:索引列的选择非常重要,不同的列选择可能会导致不同的索引效率。8、 多个表连接时没有使用索引:当查询语句涉及到多个表连接时,如果没有建立连接所需要的索引,可能会导致索引失效。

学无止境 3893

导致mysql索引失效的原因有哪些

本文将介绍mysql有哪些索引,索引失效有哪些原因,以及sql执行顺序

一名后端程序猿 6776

Palabos User Guide中文解读 | 第一章 | 介绍

译者的话:本人在学习palabos时,发现国内中文资料甚少,恰好网上可以直接搜到palabos user guide这种英文资料,加之时间充裕,便打算开始翻译,能不能完成全本翻译再说,而且文中我也会标记我不确定的地方,以传达意思为主,翻译不当的地方还请各位读者帮忙指正。 Palabos User Guide Release 1.0 r1 Copyright © 2019 University of...

Yulan Fang's notes. 6977

索引失效的问题如何排查?

首先,key一定要有值,不能是NULL 其次,type应该是ref、eq_ref、range、const等这几个 还有,extra的话,如果是NULL,或者using。1、没有正确创建索引:当查询语句中的where条件中的字段,没有创建索引,或者不符合最左前缀匹配的话,就是没有正确的创建索引。我们需要知道的是,到底要不要走索引,走哪个索引,是MySQL的优化器决定的,他会根据预估的成本来做一个决定。2、索引区分度不高:如果索引的区分度不够高,那么可能会不走索引,因为这种情况下走索引的效率并不高。

weixin_56353201的博客 1199

Pytorch.nn.Linear 解析(数学角度)

pytorch.nn.Linear 是一个类,下面是它的一些初始化参数 in_features : 输入样本的张量大小 out_features : 输出样本的张量大小 bias : 偏置 它主要是对输入数据做一个线性变换。 y=xAT+b y=xA^T+b y=xAT+b 这里A是权重矩阵,b是偏置。他们都是根据 in_features 生成 测试代码: m = torch.nn.Linea...

Medlen 1万+

GD32F105RBT6 keil工程模板

创建GD32F105RBT6的keil初始基础工程,未来的所有外设驱动都是基于这个基础工程进行扩展。

RMDYBW的博客 1927

MySQL中什么情况下会出现索引失效?如何排查索引失效?

在MySQL中,索引是用来加快检索数据库记录的一种数据结构。索引失效指的是在进行查询操作时,本应该使用索引来提升查询效率的场景下,数据库没有利用索引,而是采用了全表扫描的方式,这会大大增加查询时间和系统负担。MySQL中什么情况下会出现索引失效?如何排查索引失效?回答。

weixin_44382896的博客 8201

txt经纬度批量转面要素(附自定义ArcGIS工具箱方法)

当涉及大量txt坐标文件需要转换成面要素的时候,逐步操作工作量较大。本文由需求出发,以ArcGIS10.2为例,采用python脚本自定义ArcGIS工具,实现批量操作的目的。

m0_59216200的博客 1818

MySQL 8.0 隐式转换触发索引失效:10 个典型案例与解决方案

根本原因:隐式转换破坏数据类型一致性,导致查询优化器无法信任索引。在MySQL 8.0中,这更常见于新数据类型优化。预防措施设计表时确保列类型与查询参数匹配(如数字列用INT,字符串列用VARCHAR)。在查询中优先使用显式转换函数(如CAST、CONVERT)。利用MySQL 8.0的函数索引(CREATE INDEX ON expression)处理复杂场景。定期使用EXPLAIN分析查询计划,检查“type”列是否显示“index”或“range”(表示索引有效)。性能影响。

2501_93877799的博客 1029

手把手教你模拟登录豆瓣并爬取个人书影音数据:从Cookie解析到反爬攻防实战

在开始写代码之前,先明确我们需要的工具。:建议用3.10以上版本,方便使用一些新特性(如match语句)httpx:比requests更现代,支持HTTP/2,异步性能强,连接池复用好:解析HTML,语法简单,容错性强selenium:仅用于处理登录时的滑块验证(模拟真人)pandas:最终数据清洗和导出Excel/CSVretrying:自动重试机制,应对临时封禁:随机UA,降低特征lxml:作为BeautifulSoup的解析器,速度快为什么不只用requests?

2201_76125261的博客 577

【物联网技术】ESP8266 ESP-01/01s 固件下载烧录+STM32串口通信接线

ESP8266 ESP-01/01s 工作模式接线与MQTT固件下载烧录接线

嵌入式阿齐Archie 3万+

16条代码规范建议,涨姿势!

前几天逛知乎的时候看到一个话题:MySQL没前途了吗? 最近几年,似乎总有一种声音在说,MySQL可能不太行了,原因无非是这么几条,MySQL功能不如PG强大,原生没有分库分表不如TIDB,OLAP性能差。 可事实真的如此吗? 首先,MySQL的官网是这么介绍自己的:MySQL是世界上最受欢迎的数据库! 其次,我们直接看下数据库引擎对数据库管理系统的排名按其受欢迎程度排列,看看MySQL到底行不行! 从上图可以明显的看出,MySQL紧随它“老爹”Oracle排名第二,而且MySQL 8.0无论在功能还是性

m0_56146626的博客 128

瑞芯微RK3588部署YOLOv8模型

写下这篇博客进行记录,以防后面忘了怎么部署。

weixin_45303602的博客 3665

Redis高级项目实战,16条代码规范建议

前几天逛知乎的时候看到一个话题:MySQL没前途了吗? 最近几年,似乎总有一种声音在说,MySQL可能不太行了,原因无非是这么几条,MySQL功能不如PG强大,原生没有分库分表不如TIDB,OLAP性能差。 可事实真的如此吗? 首先,MySQL的官网是这么介绍自己的:MySQL是世界上最受欢迎的数据库! 其次,我们直接看下数据库引擎对数据库管理系统的排名按其受欢迎程度排列,看看MySQL到底行不行! 从上图可以明显的看出,MySQL紧随它“老爹”Oracle排名第二,而且MySQL 8.0无论在功能还是性

m0_57286472的博客 111

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

MySQL高级篇——索引失效的11种情况

索引优化思路、要尽量满足全值匹配、最佳左前缀法则、主键插入顺序尽量自增、计算、函数导致索引失效、类型转换(手动或自动)导致索引失效、范围条件右边的列索引失效、不等于符号导致索引失效、is not null、not like无法使用索引、左模糊查询导致索引失效、“OR”前后存在非索引列,导致索引失效、不同字符集导致索引失败,建议utf8mb4

种一棵树最好的时间是十年前,其次是现在 3万+

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

ES-Elasticsearch查看所有索引及查看某索引下的信息

1.查看所有索引,地址栏直接访问下面的连接 http://localhost:9200/_cat/indicesv&pretty 2.查看某索引下存的信息,查询的信息为索引结构信息(indexName为索引名称) GET方法:http://127.0.0.1:9200/indexNamepretty 3.查看某个索引下的所有文档数据 GET方法:http://localhost:9200/indexName/_search(需带下面的请求体,查多个索引的话可以把地址中的indexName改为inde

asdfadafd的博客 4万+

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

分库分表实战(7):抽丝剥茧 — 千万级数据之sql优化下篇

上一期,我们讲解了sql优化的一般流程,不管是优化join语句、where语句、聚合函数还是排序操作,核心在于利用索引来优化sql语句,但是,大家以为我们为字段创建了索引之后,索引就一定会生效吗?...

石杉的架构笔记 678

索引失效的情况及解决(超详细)

mysql索引优化

sy_white的博客 8万+

如何调优SQL

如何调优SQL 分下面几个问题来讨论 如何定位并优化慢查询Sql 联合索引的最左匹配原则的成因 索引是建得越多越好吗 接下来我们一一解答之: 第一个问题,如何定位并优化慢查询Sql 具体场景具体分析只提出大致思路,其实这个问题属于开放性的题目,主要考察有没有做过SQL优化,由于该问题属于经验的问题,做过了就是做过了没做过就是没做过,问了你就知道是没有做过的,没办法给出大家准确的答案只能给出大致思路,这里提前公布一下答案。然后我们再依依去讲解 第一步:根据慢日志定位慢查询SQL 第二部:使用e

myloverxx的博客 9930

SQL索引失效原因排查

数据库有一张日志表,偶然发现日志表数据库索引失效,通过排查发现原因。 log 表会产生大量日志,所以定期会将表进行备份。 通过SQL查询发现索引失效 查看哪些索引失效 select index_name from user_indexes where status <> ‘valid’; 然后发现有两个一模一样的索引名称。 发现问题是因为备份的时候导致的。 log 表 索引名称为 i...

weixin_39076313的博客 1035

索引什么时候失效 和 如何排查慢查询

1.索引什么时候失效? 经常在编写代码时候出现慢查询问题,这说明很多时候索引没有使用对。 记忆口诀:模糊匹配、类型隐转、最左匹配,这三种情况可能导致索引会失效。 以%开头的LIKE语句,模糊搜索。索引没有办法去利用,因为B+树的key没有办法再去直接比较了。 出现隐式类型转换,需要注意参数类型跟SQL查询时候类型是不是一样的,因为两个类型不同没法比较(在 Python 这种动态语言查询中需...

晓康的博客 1997

【MySQL】一次线上的OR查询导致的索引失效 附解决方案

MySQL索引失效及解决 问题发现 MySQL是一款出色的关系型数据库,在互联网行业中应用广泛。但是MySQL经常是后端开发的瓶颈,因此开发中经常涉及到MySQL的优化。建立索引是一种常见且有效的方式,但是不走索引的情况如何排查解决呢? EXPLAIN SELECT COUNT(DISTINCT(s.order_id)) AS order_count,SUM(s.estimate_cos_...

少侠露飞的学习笔记 3026

oracle函数 isex,求一条sql语句,按条件查询过期的客户信息,该怎么解决

求一条sql语句,按条件查询过期的客户信息,该怎么解决求一条sql语句,按条件查询过期的客户信息,该怎么解决日期:2014-05-16  浏览次数:20399 次求一条sql语句,按条件查询过期的客户信息建表:create table a_test(aid number(11) not null primary key,aname varchar2(100),aphone varchar2(100...

weixin_42312941的博客 573

mysql 表关联之后索引失效的原因排查

1、两表关联使用的条件字段中字段的长度是否是一致的 2、两表关联使用的条件字段中字段的编码是否是一致的 3,更本就没用到关联表中的字段去查询 今天我发现的问题就是第三个, 客户信息36万,中间表62万,关联了却没用到中间表的城市id去查导致没有用到索引 优化之后我的分页查询是这样的 if("2".equals(customer.getSourceType()) &&customer.getHoHouseCustomer()!=null &&Str

zhaofuqiangmycomm的博客 5150

SQL索引失效的几种情况

1、 没有正确使用符合索引 例如我们根据user表中的A,B,C创建一个符合索引 create index on user(A,B,C) 实际上mysql是为我们创建了三个索引 A AB ABC 假如你从B 或者C 开始查 就没有用到索引 select B from user while B = ‘b’ 2、范围查询右边的列使用索引无效 select A from user where C > 1 and A = 'a' 3、对索引列进行运算,索引失效 select A from user

weixin_45844836的博客 5228
上一篇: 字节跳动后台Java2020面试真题(含手写代码及设计题)
下一篇: 【MySQL技术内幕】:InnoDB存储引擎体系架构及关键特性
少侠露飞
博客等级 码龄9年 214粉丝 117原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值