Mysql为什么有时候会选错索引

自动驾驶轨迹规划算法——Apollo Lattice Planner Apollo Lattice Planner是百度Apollo自动驾驶系统中的一种基于采样的实时轨迹规划算法。其核心思想是在离散化的状态空间中,对终端状态进行采样,并通过多项式曲线连接当前状态与候选终端状态,形成候选轨迹集,最后基于代价函数选择最优轨迹。该算法将车辆可达状态按纵向距离、横向偏移和速度等维度规则离散化,形成"格点"状态空间。 Lattice Planner通过三个主要步骤实现轨迹规划:1)终端状态采样,在规划时域内枚举多种驾驶意图;2)轨迹生成,使用五次多项式连接起点与各终 阅读详情

案例

正常情况

有一个表t ( id, a , b ),id是主键索引,a是Normal索引。

正常情况下,针对a进行查询,可以走索引a
在这里插入图片描述
并且查询的数量和预估扫描行数是差不多的,都是10001行
在这里插入图片描述

奇怪的现象

随着时间的变化,后面可能就会发生下面的情况
在这里插入图片描述
根据explain计划,我们发现数据还是那么多,但是不走a索引了,并且优化器知道有a索引,但是最终还是走了全表扫描。

优化器的逻辑

先了解一下优化器
选择索引是优化器的工作,而优化器选择索引的目的,是找到一个最优的执行方案,并用最小的代价去执行语句。在数据库里面,扫描行数是影响执行代价的因素之一。扫描的行数越少,意味着访问磁盘数据的次数越少,消耗的 CPU 资源越少(扫描行数并不是唯一的判断标准,优化器还会结合是否使用临时表、是否排序等因素进行综合判断)

下面只讨论扫描行数带来的影响
那么优化器是怎么去估算需要扫描多少行?
在这里插入图片描述
我们可以通过命令看到有一个Cardinality(基数),选择索引需要扫描的行数就是通过它来判断的,它代表一个索引上不同的值的个数,值越大说明区分度越高,那么越有可能走这个索引

优化器的选择一定对么?

上面看到针对下面这个sql,优化器觉得全表扫描更合适,但实际上真的是速度最快的么?

select * from t where a between 10000 and 20000;

我们实际执行一下:
在这里插入图片描述
不接受优化器的建议,强行走a索引执行一下:
在这里插入图片描述
重点看3个指标:Query_time(执行耗时)、Rows_sent(返回行数)、Rows_examined(扫描/行数)
我们发现强行走索引a其实更快,实际扫描行数也少。那么为什么优化器不走索引a呢?

我们再执行一个命令(更新表的统计信息):

ANALYZE TABLE t;

然后我们再看一下执行计划:

explain select * from t where a between 10000 and 20000;

在这里插入图片描述
发现优化器竟然又选择了索引a,说明是因为统计信息不准确,没有及时更新导致优化器进行了错误的选择。
接着实际执行一下:

select * from t where a between 10000 and 20000;

在这里插入图片描述
我们发现实际的扫描行数和预估的扫描行数对上了,并且也确实走了索引a,耗时也降下来了
最后我们再看一下索引的统计信息
在这里插入图片描述
统计信息确实和上面不一样了,更新了。但是这里有个问题是:虽然统计信息不一样了(能确保确实更新索引统计信息的sql起作用了)但统计信息和一开始也差不多,为什么Cardinality值差不多的情况下,优化器做出了不一样的选择?
因为实际上表数据经历了大量的删除、新增操作,Cardinality不会更新一些还未提交的事务数据,所以看似基数差不多,实际上基数不一样。优化器对主键的判断是基于实际表行数来判断的,所以主键的判断是准的,不准的是其他索引的统计信息。

总结

本文讨论了Mysql(InnoDB)在索引统计信息不准确或更新不及时的情况下,优化器基于统计信息进行粗估的执行计划,可能会选错索引。
我们一般应对的方法如下:

  1. 更新索引统计信息
  2. 修改SQL语句强制走固定索引
  3. 新增索引(比如上面新增一个索引a,b)
  4. 删除索引(假设优化器选择了索引b,确保该索引没有其他作用的前提下,那么删掉索引b,可能就会走索引a了)
RT-2(robotics-transformer2)论文--阅读笔记 谷歌RT-2机器人论文的阅读笔记。 阅读详情

相关推荐

OAI数据集申请下载全攻略:从个人NDA账号注册到数据包下载的保姆级避坑指南

本文提供OAI数据集申请下载的完整指南,涵盖从个人NDA账号注册到数据包下载的全流程。重点解析login.gov验证陷阱、浏览器兼容性问题、NDA权限申请技巧及nda-tools高效使用方法,帮助医学影像研究者避开常见技术障碍,快速获取全球骨关节炎研究数据库OAI的宝贵数据资源。

weixin_28698059的博客 746

MySql为什么会选错索引?如何解决?

MySql选错索引

hncujing的专栏 852

拆开华为BBU5900,看看5G基站的大脑里到底装了啥?

本文深度拆解华为BBU5900,揭示5G基站核心处理单元的硬件架构与设计哲学。通过详细解析模块化设计、智能电源系统和动态散热方案,展现其支撑千兆速率、毫秒级时延的技术奥秘,为5G网络部署提供实用参考。

weixin_31456563的博客 558

MySQL为什么有时候会选错索引?

MySQL为什么有时候会选错索引?优化器逻辑索引选择异常和处理 抛出问题:一条本来可以执行得很快的语句,却由于 MySQL 选错了索引,而导致执行速度变得很慢? 首先举个例子: 先建一个简单的表,表里有 a、b 两个字段,并分别建上索引: CREATE TABLE `t` ( `id` int(11) NOT NULL, `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL, PRIMARY KEY (`id`), KEY `a` (`a`

香农三定律的博客 481

为什么需要知识图谱?什么是知识图谱?——KG的前世今生

我的知乎专栏,对知识图谱感兴趣的朋友可以关注。标题的命名顺序可能让有的读者不太习惯。通常在介绍一个陌生事物的应用前,我们先给出其定义。之所以换个顺序,是为了不让读者一开始就接触比较冰冷生硬的概念刻板描述(后面我尽量用更具体、准确的例子来表达),另一方面也是为了通过现实生活中的例子自然的引入知识图谱的概念。希望通过这种方式加深读者的印象和理解。为了减轻读者理解的负担,我尽可能地避免引入过多的概念和技术

SimmerChan的专栏 8万+

告别手动干预:深入浅出LPDDR5的Background ZQ校准与DVFSQ切换避坑指南

本文深入解析LPDDR5的Background ZQ校准与DVFSQ切换技术,帮助工程师实现DRAM阻抗校准的自动化管理。通过详细配置指南和实战案例,揭示如何避免动态电压调节下的模式切换陷阱,提升信号完整性和系统能效。特别适合嵌入式系统和移动终端开发者参考。

weixin_30329623的博客 451

MySQL用错索引

周四了,MuSQL为什么会用错索引,之前在工作中就有遇到过MySQL用错索引的情况,当时使用force强制指定了索引才解决。除了强制指定使用索引外,还可以诱导MySQL使用正确的索引。在使用explain分析MySQL的索引计划的时候,有一个预估行扫描数是一个采样的结果,计算内存页采样的平均值再乘以内存页的个数。在工作中遇到MySQL使用索引出问题的情况越来越少了,可能是因为现在数据库的种类现在越来越多了。本身强制指定索引就是一个非常不通用的做法,因为索引本身是变更的,代码需要跟着索引去变更。......

小知识折射大智慧 580

mos管结电容等效模型_MOS管的防冲击防反接电路

MOS管的反接和抑制冲击一:原理分析MOS管由于生产工艺等因素,会产生相应的寄生电容,体二极管等。Mos管的寄生电容如图1所示,可以看到其具有三个寄生电容:G和S的电容Cgs;G和D的电容:Cgd,也称为反向传输电容、米勒电容、Crss;D和S的电容Cds。D和S之间的体二极管D1.图 1:MOS管等效模型寄生电容的数值可以从元器件的datasheet中得到,如图2,图3:Ciss(输入电容)=C...

weixin_29179583的博客 1854

MySQL实战45讲学习笔记:MySQL为什么有时候会选错索引?(第10讲)

一 、本节内容概要 前面我们介绍过索引,你已经知道了在 MySQL 中一张表其实是可以支持多个索引的。但是,你写 SQL 语句的时候,并没有主动指定使用哪个索引。也就是说,使用哪个索引是由MySQL 来确定的。 不知道你有没有碰到过这种情况,一条本来可以执行得很快的语句,却由于 MySQL 选错了索引,而导致执行速度变得很慢? 我们一起来看一个例子吧。 我们先建一个简单的表,表...

weixin_30235225的博客 1014

聚宽策略实盘新路径:不开通QMT , 小资金自动化交易解决方案

聚宽策略实盘新路径:不开通QMT , 小资金自动化交易解决方案

u011111246的博客 1466

Claude Code插件安装与VSCode深度集成实战指南

Claude Code是一款专为IDE设计的AI编程助手插件,其核心价值在于将自然语言意图转化为可运行代码,从而优化开发者认知带宽分配。它依赖Node.js运行时、git版本上下文和VSCode编辑器API三者协同工作,技术原理涉及本地进程通信、权限策略绕过、上下文感知补全等关键机制。该工具显著提升工程效率,适用于CLI开发、EXIF元数据处理、异步逻辑生成等典型JavaScript/TypeScript应用场景。本文聚焦Claude Code插件在VSCode中的真实落地链路,覆盖Windows/macO

weixin_34006468的博客 473

MySQL 索引选错的情况

本文总结了一些 MySQL 索引选错的情况、选错的原因以及对应的解决方案。

DDghost的博客 1046

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

MySQL 为什么有时候会选错索引?

优化器不仅会估算扫描行数,还会考虑普通索引还要进行回表操作,主键索引不需要回表,有些时候尽管主键索引的估算扫描行数多于普通索引,但是普通索引需要回表,所以优化器综合考虑用的还是主键索引。

技术分享,读书笔记,面试宝典,算法积累,应有尽有~ 379

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

10讲MySQL为什么有时候会选错索引

前面我们介绍过索引,你已经知道了在MySQL中一张表其实是可以支持多个索引的。但是,你写SQL语句的时候,并没有主动指定使用哪个索引。也就是说,使用哪个索引是由MySQL来确定的。 不知道你有没有碰到过这种情况,一条本来可以执行得很快的语句,却由于MySQL选错了索引,而导致执行速度变得很慢? 我们一起来看一个例子吧。 我们先建一个简单的表,表里有a、b两个字段,并分别建上索引: CREATE T...

通往神秘的道路的专栏 424

android 蓝牙通讯demo

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

10 MySQL为什么有时候会选错索引?

Hello!欢迎各位新老朋友来看小弟博客,祝大家事业顺利,财源广进!!前面我们介绍过索引,你已经知道了在 MySQL 中一张表其实是可以支持多个索引的。但是,你写 SQL 语句的时候,并没有主动指定使用哪个索引。也就是说,使用哪个索引是由 MySQL 来确定的。不知道你有没有碰到过这种情况,一条本来可以执行得很快的语句,却由于 MySQL 选错了索引,而导致执行速度变得很慢?我们一起来看一个例子吧。

qq_41655898的博客 1070

【实战篇】MySQL为什么有时候会选错索引?

然后,我们往表 t 中插入 10 万行记录,取值按整数递增,即:(1,1,1),(2,2,2),(3,3,3) 直到 (100000,100000,100000)。这条查询语句的执行也确实符合预期,key 这个字段值是’a’,表示优化器选择了索引 a。接下来,我们进行如下操作:这时候,session B 的查询语句 select * from t where a between 10000 and 20000 就不会再选择索引 a 了。

shenyongsi的博客 1114

MySQL实战——为什么MySQL有时候会选错索引

已知MySQL中一张表是可以支持多个索引的,但是我们写SQL语句的时候并没有主动指定使用哪个索引,也就是说使用哪个索引是由MySQL来确定的。所以可能会出现这种情况:本来一句可以执行的很快的SQL语句却由于MySQL选错了索引导致执行的很慢。现在有如下的例子:先建一个简单的表,表里有 a、b 两个字段,并分别建上索引:这个语句很简单,a上有索引,使用索引a,而实质上优化器选择的确实也是索引a。扫描的行数是10001行再做如下操作:session A 开启了一个事务。

PnJgHT的博客 280

- MySQL为什么有时候会选错索引?

前面我们介绍过索引,你已经知道了在MySQL中一张表其实是可以支持多个索引的。但是,你写SQL语句的时候,并没有主动指定使用哪个索引。也就是说,使用哪个索引是由MySQL来确定的。不知道你有没有碰到过这种情况,一条本来可以执行得很快的语句,却由于MySQL选错了索引,而导致执行速度变得很慢?我们一起来看一个例子吧。然后,我们往表t中插入10万行记录,取值按整数递增,即:(1,1,1),(2,2,2),(3,3,3) 直到(100000,100000,100000)。

qq_33240556的博客 928

MySQL为什么有时候会选错索引

然后,我们往表 t 中插入 10 万行记录,取值按整数递增,即:(1,1,1),(2,2,2),(3,3,3) 直到 (100000,100000,100000)。首先从磁盘中随机加载N份数据页,然后统计不同的值,取得平均值后乘以索引页面的数量,当变更的数据行数超过 1/M 的时候,会自动触发重新做一次索引统计。MySQL中索引的选择是由优化器来决定的,而决定用什么索引的原因有很多,比如 区分度、扫描行数、是否使用了临时表、是否需要排序、是否需要回表等。这时,默认的 N 是 20,M 是 10。

Sudo_Wang的学习记录 574

10 | MySQL 为什么有时候会选错索引?

文章目录10 | MySQL 为什么有时候会选错索引?优化器的逻辑索引选择异常和处理小结上期问题时间 10 | MySQL 为什么有时候会选错索引? 在 MySQL 中一张表其实是可以支持多个索引的。但是,你写 SQL 语句的时候,并没有主动指定使用哪个索引。也就是说,使用哪个索引是由 MySQL 来确定的。 不知道你有没有碰到过这种情况,一条本来可以执行得很快的语句,却由于 MySQL 选错了索引,而导致执行速度变得很慢? 我们先建一个简单的表,表里有 a 、 b 两个字段,并分别建上索引: CREATE

sdaujsj1的博客 246

10 | MySQL为什么有时候会选错索引?

前面我们介绍过索引,你已经知道了在MySQL中一张表其实是可以支持多个索引的。但是,你写SQL语句的时候,并没有主动指定使用哪个索引。也就是说,使用哪个索引是由MySQL来确定的。 不知道你有没有碰到过这种情况,一条本来可以执行得很快的语句,却由于MySQL选错了索引,而导致执行速度变得很慢? 我们一起来看一个例子吧。 我们先建一个简单的表,表里有a、b两个字段,并分别建上索引: CREA...

weixin_33980459的博客 219
上一篇: WGAN的概念和应用
下一篇: Agent无反馈规划【实践】
帅东
博客等级 码龄11年 676粉丝 88原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值