五分钟,让你明白mysql是怎么选择索引《死磕mysql系列六》(代码片段)

咔咔- 咔咔-     2023-01-28     478

关键词:

系列文章

二、一生挚友redo log、binlog《死磕MySQL系列 二》

三、MySQL强人“锁”难《死磕MySQL系列 三》

四、S 锁与 X 锁的爱恨情仇《死磕MySQL系列 四》

五、如何选择普通索引和唯一索引《死磕MySQL系列 五》

如果你对索引的知识点还不太清楚,可以直接通过传送门查看咔咔总结的索引知识点。

揭开MySQL索引神秘面纱

索引是为加速查询速度,创建的索引也符合所有规则,但MySQL就是不使用理想的索引,导致查询速度变慢并产生大量慢查询记录。

今天就从这个问题来聊聊MySQL选择索引时都做一些什么事情。

一、如何选择索引

影响优化器的几大因素

一条查询SQL执行需要经过连接器、分析器、优化器、执行器,而选择索引的重任就交给了优化器

优化器在多个索引中选择目的是为了找出执行代价最低的方案。

影响优化器选择无非就这几个因素,扫描行数、是否使用了临时表、是否使用文件排序。

临时表、文件排序这个两个点会在后期文章给大家慢慢引出,今天只聊扫描行数。

扫描行数越少则访问磁盘数据的次数就越少,消耗的CPU资源越少。

那么这个扫描行数是从哪里取的呢?

扫描行数从何而来?

创建索引一直提倡大家给区分度高的列建立索引,在一个索引上不同值的个数称之为基数(cardinality)。

使用show index from table_name可以查看每个索引的基数是多少。

索引基数怎么计算

MySQL使用采样统计的方法,会选出N个数据页,每个数据页大小16kb,接着统计选出来的数据页上的不同值就会得到一个平均值,用平均值在乘以索引的页面数得到的结果就是这个索引的基数。

表数据是持续增加或删减的,统计的这个数据也不是时时变化的,当变更的数据超过1/M时会自动触发重新计算。

这个M是根据参数innodb_stats_persistent的值选则的,设置为on值为10,设置为off值为16。

索引基数通过这种方式计算不是精准的但也差不了多少

为什么优化器选择了扫描行数多的索引?

第一种情况

表增删十分频繁,导致扫描行数不准确

第二种情况

假设你主键索引扫描行数是10W行,而普通索引需要扫描5W行,这种情况就会遇到优化器选择了扫描行数多的。

在索引那一期文章中知道主键索引是不需要回表的,找到值直接就返回对应的数据了。

而普通索引是需要先拿到主键值,再根据主键值获取对应的数据,这个过程优化器选择索引时需要计算的一个成本。

如何解决这种情况

扫描行数不准确时可以执行analyze table table_name命令,重新统计索引信息,达到预期优化器选择的索引。

二、索引选择异常如何处理

方案一

在MySQL中提供了force index来强制优化器使用这个索引。

使用方法:select * from table_name force index (idx_a) where a = 100;

但别误解force index的使用方法,之前在代码中看到这样一个案例,给查询列使用了函数操作导致使用不上索引,然后这哥们就直接使用force index,肯定不行的哈!

当优化器没有正确选择索引时是可以使用这种方案来解决。

缺点

使用force index的缺点相信大家也知道就是太死板,一旦索引名字改动就会失效。

方案二

删掉误选的索引,简单粗暴,很多索引建立其实也是给优化器的一个误导,直接删掉即可。

方案三

修改SQL语句,主动引导MySQL使用期望的索引,一般情况这种做法使用的很少除非你对系统十分熟悉,否则尽量少操作。

三、总结

优化器选择索引首先会根据扫描行数再由执行成本决定。

当索引统计信息不准确时,使用analyze table 解决。

优化器选择了错误的索引,只用force index来快速矫正,再通过优化SQL语句来引导优化器选择正确的索引,最暴力的手法是直接删除误选的索引。

坚持学习、坚持写作、坚持分享是咔咔从业以来所秉持的信念。愿文章在偌大的互联网上能给你带来一点帮助,我是咔咔,下期见。

五分钟告诉你什么是mysql的覆盖索引(代码片段)

文章目录五分钟告诉你什么是MySQL的覆盖索引覆盖索引总结参考五分钟告诉你什么是MySQL的覆盖索引前面我们已经对MySQL索引底层原理多少有一定的了解了,还不是很了解的小伙伴可以看我之前的博文:《不会吧不会吧,难... 查看详情

五分钟让你明白linux的软链接和硬链接的用法

参考技术A 什么是软链接和硬链接,很多人对这个概念比较模糊,这里帮助你明白他们之间的区别和用法。为解决文件的共享使用,Linux系统引入了两种链接:硬链接(hardlink)与软链接(又称符号链接,即softlink或symboliclink)。... 查看详情

五分钟搞懂mysql索引下推(代码片段)

大家好,我是老三,今天分享一个小知识点——索引下推。如果你在面试中,听到MySQL5.6”、“索引优化”之类的词语,你就要立马get到,这个问的是“索引下推”。什么是索引下推索引下推(IndexConditionPushdown&... 查看详情

五分钟搞懂mysql索引下推(代码片段)

大家好,我是老三,今天分享一个小知识点——索引下推。如果你在面试中,听到MySQL5.6”、“索引优化”之类的词语,你就要立马get到,这个问的是“索引下推”。什么是索引下推索引下推(IndexConditionPushdown&... 查看详情

图解|从根上彻底理解mysql的索引(代码片段)

这篇文章会让你明白什么是索引,彻底理解B+树和索引的关系;彻底理解主键索引、普通索引、联合索引;了解什么是HASH索引,InnoDB和MyISAM索引的不同实现方式;轻松理解后续的索引使用规则。这是图解MySQL的第4篇文章,这篇文... 查看详情

白日梦的mysql专题(第38篇文章)8分钟回顾mysql的索引(代码片段)

目录公众号首发-推荐阅读原文-格式更好看一、导读二、聚簇索引三、二级索引四、联合索引4.1、什么是联合索引4.2、左前缀原则4.3、联合索引的分组&排序五、覆盖索引六、倒排索引公众号首发-推荐阅读原文-格式更好看点击... 查看详情

5分钟让你明白http协议(代码片段)

一、HTTP简介1.http协议介绍HTTP协议(HyperTextTransferProtocol,超文本传输协议)是因特网上应用最为广泛的一种网络传输协议,所有的WWW文件都必须遵守这个标准。HTTP是基于TCP/IP通信协议来传递数据(HTML文件,图片文件,查询结果等... 查看详情

sql优化及原理详解,五分钟读懂sql优化

参考技术A在我而言这算是一个复习,然后总结出来给大家当个教材吧。我也是看视频总结出来的笔记,所以说的都很简单和浅薄。有不全面或者偏颇的地方欢迎指出,共同交流进步哈。(因为我当时是看视频总结的笔记,所以... 查看详情

你知道什么是ci/cd吗?不懂?五分钟让你彻底理解!

在CI/CD和DevOps领域中,持续交付和持续部署是一个老生常谈的话题。持续集成这个术语最早是在1994年由GradyBooch提出。微服务提出者MartinFlower在2014年发表的论文《Microservice》中也对软件开发持续集成提供了可参考原则。持续集成... 查看详情

(转)5分钟让你明白“软链接”和“硬链接”的区别

今天在知乎上看到一篇十分有趣的问题:如何评价微软高级工程师痴迷于softlink这一linux常见概念?虽然又是知名撕逼王曾某的撕逼帖,但是我还是想就题目中链接的问题简单地讲讲。什么是链接?链接简单说实际上是一种文件... 查看详情

你还不知道vrrp是什么?分分钟让你明白vrrp的作用!(代码片段)

文章目录VRRP协议单网关的缺陷多网关存在的问题VRRP基本概述VRRP基本结构VRRP主备备份工作过程Master发生故障实验下行接口、AR1出现故障上行接口downVRRP协议一种网关备份协议实现网关的备份解决多个网关之间互相冲突的问题单网... 查看详情

java四种引用类型原理你真的搞明白了吗?五分钟带你深入理解!

Java中一共有4种引用类型(其实还有一些其他的引用类型比如FinalReference):强引用、软引用、弱引用、虚引用。其中强引用就是我们经常使用的Objecta=newObject();这样的形式,在Java中并没有对应的Reference类。本篇文章主要是分析软引... 查看详情

mongodb数据库|三分钟学会mongodb索引,快来看看与mysql索引有何不同?(代码片段)

目录一、创建索引1、创建索引2、通过索引查询二、复合索引三、索引内嵌文档四、索引基数五、explain六、为何不使用索引七、固定集合一、创建索引1、创建索引>db.student.createIndex("name":1)"numIndexesBefore":1,"numIndex... 查看详情

人工智能有什么用?五分钟时间,让你彻底了解ai人工智能!

人工智能是现在普及的最全面的东西,基本上每个人都会用上人工智能这个东西,但是有很多人就会提出疑问了,为什么我自己不知道呢?因为人工智能是隐藏我们平时用的手机里,就比如说手机地图会根据你的目的地推荐最近... 查看详情

mysql中的“my”是什么意思?

...比如:count(*)慢该如何解决?对于千万级的大表,MySQL要怎么优化?SQL使用Join好,还是多次Select好?1000多万条数据,建了索引还是慢,该怎么办? 仔细想想,我当初在用MySQL的过程中 查看详情

linux下怎么修改mysql的字符集编码

参考技术A  可直接进入mysql进行更改,具体如下:  1.查找/etc目录下是否有my.cnf文件;#ls-l|grepmy.cnf(在/etc下查找是否有my.cnf文件存在)2.如果没有就要从/usr/share/mysql,拷贝一个到/etc下,在/usr/share/mysql目录下有五个后缀为.cnf的... 查看详情

大厂面试快问快答,10分钟搞定mysql夺命20问,你都能接住吗?(代码片段)

号外号外!《死磕Java并发编程》系列连载中,大家可以关注一波:「死磕Java并发编程05」阿里面试失败后,一气之下我图解了Java中18把锁「死磕Java并发编程04」说说JavaAtomic原子类的实现原理「死磕Java并发编程03... 查看详情

大厂面试快问快答,10分钟搞定mysql夺命20问,你都能接住吗?(代码片段)

号外号外!《死磕Java并发编程》系列连载中,大家可以关注一波:「死磕Java并发编程05」阿里面试失败后,一气之下我图解了Java中18把锁「死磕Java并发编程04」说说JavaAtomic原子类的实现原理「死磕Java并发编程03... 查看详情