一文彻底搞懂Mysql索引优化

article/2025/11/7 5:43:24

专属小彩蛋:前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站(前言 - 床长人工智能教程) 

目录

一、索引介绍

二、性能分析

三、查询优化

四、排序优化

五、关联查询优化

六、分组优化

七、慢查询日志


一、索引介绍

(1)什么是mysql的索引

mysql官方对于索引的定义:索引是帮助mysql高效获取数据的数据结构。mysql在存储数据之外,数据库系统中还维护着满足特定查找算法的的数据结构,这些数据结构以某种引用(指向)表中的结构,这样我们就可以通过数据结构上实现的高级查找算法来快速找到我们想要的数据。而这种数据结构就是索引。

简单理解为“排好序的可以快速查找数据的数据结构”。

(2)索引数据结构

下图就是一种可能的二叉树的索引方式:

 二叉树数据结构的弊端:当极端情况下,数据递增插入时,会一直向右插入,形成链表,查询效率会降低。

MYSQL中常用的索引数据结构有BTree索引(myisam普通索引)B+Tree索引(Innodb普通索引),hash索引(memory存储索引)等等。

(3)索引优势

提高数据检索的效率,降低数据库的IO成本。通过索引对数据进行排序,降低数据排序的成本,降低了cpu的消耗。

(4)索引劣势

        索引实际上也是一张表,保存了主键和索引的字段,并且指向实体表的记录,所以索引也是需要占用空间的,在索引大大提高查询速度的同时,却会降低表的更新速度,在对表进行数据增删改的同时,mysql不仅要更新数据,还需要保存一下索引文件,每次更新添加了的索引列的字段,都会去调整因为更新带来的减值变化后的索引的信息。

(5)索引使用场景

哪些情况推荐建立索引?

  1. 主键自动建立唯一索引
  2. 频繁作为查询条件的字段应该创建索引(where后面的语句)
  3. 查询中与其他表关联的字段,外键关系建立索引
  4. 多字段查询下倾向创建组合索引
  5. 查询中排序的字段,排序字段若通过索引去访问将大大提高排序速度
  6. 查询中统计或者分组字段

哪些情况不推荐建立索引?

  1. 表记录太少
  2. 经常增删改的表
  3. where条件里用不到的字段不建立索引

(6)索引分类

  • 主键索引(primary key)
  • 唯一索引(unique)
  • 单值索引(index)
  • 复合索引

二、性能分析

(1)mysql常见瓶颈

sql中对大量数据进行比较,关联,排序,分组时cpu的瓶颈。

实例内存满足不了缓存数据或排序等需要,导致产生大量的物理IO,查询数据时扫描过多数据行,导致查询效率低。

(2)Explain 执行计划

使用Explain关键字可以模拟优化器执行sql查询语句,从而知道mysql是如何处理sql语句的,可以用来分析查询语句或是表的结构的性能瓶颈。其作用:

  • 表的读取顺序
  • 哪些索引可以使用
  • 数据读取操作的操作类型
  • 哪些索引被实际使用 
  • 表之间的引用
  • 每张表有多少行被优化器查询

Explain 关键字使用起来比较简单: explain + SQL语句

 如下所示,我们查看一个多表根据id关联的sql语句执行计划。

(3)Explain 重要字段名

id:select查询的序列号,表示查询中执行select子句或操作表的顺序。

  • id相同时,执行顺序由上至下。
  • id不同,如果是子查询,id的序号会递增,id值越大优先级越高,则先被执行。
  • id相同和不同都存在时,id相同的可以理解为一组,从上往下顺序执行,所有组中,id值越大,优先级越高越先执行。

select_type:询的类型,常见值有:

  • SIMPLE: 简单的select查询,查询中不包含子查询或union。
  • PRIMARY: 查询中若包含任何复杂的子部分,最外层查询则被标记为Primary。
  • DERIVED: 在FROM列表中包含的子查询被标记为DERIVED(衍生),mysql会递归执行这些子查询,把结果放在临时表里。
  • SUBQUERY: 在select或where列表中包含了子查询。

table:显示这一行的数据是关于哪张表的。

type:访问类型排序

 

  • System:表只有一行记录(等于系统表),这是const类型的特例,平时不会出现,这个也可以忽略不计。示例:

  • Const:表示通过索引一次就找到了,const用于比较primary key或者unique索引,因为只匹配了一行数据,所以很快,如将主键置于where列表中,mysql就能将该查询转换为一个常量。示例:

  • eq_ref: 唯一性索引扫描,对于每个索引建,表中只有一条记录与之匹配,常见于主键或者唯一索引扫描, 常用于联表查询,示例:

  •  ref:非唯一性索引扫描,返回匹配某个单独值的所有行,本质上也是一种索引访问,它返回所有匹配某个单独值的行,然而,它可能会找到多个符合条件的行,所以它应该属于查找和扫描的混合体。示例:

  •  range:只检索给定范围的行,使用一个索引来选择行,key列显示使用了哪个索引一般就在你的where语句中出现了between,<,>,in等的查询这种范围扫描索引扫描比全表扫描要好,因为它只需要开始于索引的某一点,结束于另一点,不用扫描全部索引。示例:

  •  index: full index scan,index与all 区别为index类型只遍历索引树,这通常比all快,因为索引文件通常比数据文件小,也就是说虽然all和index都是读全表,但index是从索引中读取的,而all是从硬盘中读取的。示例:由于t1表只有id和content两个字段,并且id,content 都建立了索引,所以直接从索引文件读取数据。
  •  all: full table scan,将遍历全表来找到匹配的行。

从最好到最差依次为:system> const > eq_ref> ref> range> index> all 。 一般来说, 最好保证查询能达到range级别,最好能达到ref级别以上。

possible_keys: 显示可能应用在这张表中的索引,一个或多个,查询涉及到的字段上如果存在索引,则该索引将会被列出来,但不一定会被查询到实际使用上。

key: 查询中实际使用的索引,如果是null,则没有使用索引。

 当 查询条件改为 is not null 时,索引失效,则possible_keys 和 key 就不一致了。

ref :显示索引的哪一列被使用了,哪些列或常量被用于查找索引列上的值。

 rows:显示mysql认为它执行查询时必须检查的行数,一般越少越好。

  • extra: 一些常见的重要的额外信息。
  • Using filesort:mysql 无法利用索引完成的排序操作称为“文件排序”。(代表排序字段没有使用索引,效率较低)

  • Using temporary: mysql在对查询结果排序时使用临时表,常见于排序order by 和分组查询 group by。

  • Using index:表示索引被用来执行索引键值的查找,避免访问了表的数据行,效率不错(代表查询的字段都是从索引文件获取到的)示例:从索引文件获取

  未从索引文件获取

  • Using where:表示使用了where过滤。

 三、查询优化

示例前提:我们建了一个( sname ,age,score) 的组合索引。演示失效的场景。

(1)索引失效

  • 最佳左前缀法则:如果索引了多列,要遵循最左前缀法则,指的是查询从索引的最左前列开始并且不跳过索引中的列。示例:我们建了一个 sname ,age,score 的组合索引,当我们执行如下四个前三个sql 索引生效,第四个sql其实只有sname索引生效,如果执行的sql为:

 select * from students where age = 22; 则索引完全失效,没有符合最左匹配原则。

  • 不在索引列上做任何计算,函数操作,会导致索引失效而转向全表扫描。

  • 存储引擎不能使用索引中范围条件右边的列,示例:只有sname 和 age的索引生效,score索引并没有用到 

  • mysql在使用不等于时无法使用索引会导致全表扫描

  • is null可以使用索引,但是is not null 无法使用索引。

 

  • like 以通配符开头会使索引失效导致全表扫描。

  • 字符串不加单引号索引会失效

  • 使用 or 连接时索引失效

 总结:假设index(a,b,c)复合索引:注意or 不会生效,and 会自动调整顺序为最左前列。

 

建议:

  • 对于单值索引,尽量选择针对当前查询字段过滤性更好的索引, 
  • 对于组合索引,当前where查询中过滤性更好的字段在索引字段顺序中位置越靠前越好,尽量选择能够包含在当前查询中where子句中更多字段的索引,尽量通过分析统计信息和调整查询的写法来达到选择合适索引的目的。

 四、排序优化

  • 尽量避免使用Using  filesort的方式排序
  • order by 语句使用索引最左前列或使用where子句与order by 子句条件组合满足索引最左前列。
  • where 子句中如果出现索引范围查询会导致order by 索引失效

 五、关联查询优化

内连接时,mysql会自动把小结果集的选为驱动表,所以大表的字段最好加上索引,左外连接时,左表会全表扫描,所以右边大表字段最好加上索引,右外连接同理,最好保证被驱动表上的字段建立了索引。

class表为驱动表,book表为被驱动表,一般我们将数据量少的表作为驱动表,因为left join 或者 right join 时驱动表不可避免的需要全表扫描,

 给book表的card字段建立索引后,再次测试

六、分组优化

和排序优化思路类似

 七、慢查询日志

mysql 的慢查询日志是mysql 提供的一种日志记录,他用来记录在mysql 中响应时间超过阈值的语句,具体运行时间超过long_query_time值的sql,则会被记录到慢查询日志中。可以用它来查看哪些sql超过了我们最大忍耐时间值。

默认情况下,mysql数据库没有开启慢查询日志,需要手动设置参数。

查看是否开启:show variables like '%slow_query_log%'

开启日志:set global slow_query_log = 1;

查看超时的sql 记录 日志:mysql的数据文件夹下

5.5\Data\设备名称-slow.log

注意:非调优场景下,一般不建议启动该参数,慢查询日志支持将日志记录写入文件,开启慢查询日志会或多或少带来一定的性能影响。

 专属小彩蛋:前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站(前言 - 床长人工智能教程)


http://chatgpt.dhexx.cn/article/3kCNWrvP.shtml

相关文章

MYSQL通过索引进行优化

MYSQL通过索引进行优化 一&#xff1a;什么是索引&#xff1a; 在关系数据库中&#xff0c;索引是一种与表有关的数据库结构&#xff0c;它可以使对应于表的 SQL 语句执行得更快。索引的作用相当于图书的目录&#xff0c;可以根据目录中的页码快速找到所需的内容。 对于数据…

MySQL索引优化(超详细)

Mysql索引优化 1 索引介绍 1.1 什么时MySQL的索引 ​ MySQL官方对于索引的定义:索引是帮助MySQL高效获取数据的数据结构。 ​ MySQL在存储数据之外&#xff0c;数据库系统中还维护着满足特定查找算法的数据结构&#xff0c;这些数据结构以某种引用(指向)表中的数据&#xff…

MySQL索引(二)索引优化方案有哪些

在上一篇文章中&#xff0c;我们介绍了MySQL中常见的索引类型以及每种索引的各自特点&#xff0c;那么这篇文章带你来与我一起看一下聚集索引与二级索引的关系&#xff0c;最后在附上常见的索引优化方案。首先我们还是看一下聚集索引和二级索引的区别 MySQL索引&#xff08;一…

【MySQL】索引优化原则

前面几篇博文谈到索引使用场景和explain命令帮助我们分析索引的执行情况&#xff0c;今天进入正题&#xff0c;来谈谈索引优化的原则。 1、全值匹配 查询语句尽量使用全值匹配。 2、左前缀原则 如果一个索引是组合索引&#xff0c;索引了多列&#xff0c;要遵循左前缀原则…

MySQL:索引优化、查询优化

一、哪些情况适合创建索引 1、字段的数值有唯一性的限制&#xff1b; 业务上具有唯一特性的字段&#xff0c;即使是组合字段&#xff0c;也必须建成唯一索引&#xff1b; 说明&#xff1a;创建唯一索引会影响添加的速度&#xff08;在添加的时候会维护索引&#xff09;&…

Mysql-索引优化

一、索引基本知识 1、索引的优点 很大程度上减少服务器扫描的数据量很大程度上避免服务器排序和临时表将随机IO变成顺序IO 2、索引的用处 使用索引列可以快速查找Where条件的行数据 mysql> explain select * from emp where empno 7469; ----------------------------…

MySQL索引优化总结

前言&#xff1a;相信大家都知道索引可以大大提高MySQL的检索速度&#xff0c;但是真正在平时工作中写SQL&#xff0c;真的会考虑到这条SQL如何能够用上索引提升执行效率&#xff1f;本篇博客详细的介绍了索引优化的20个原则&#xff0c;只要在工作中能够随时应用到&#xff0c…

【MySQL】深入理解MySQL索引优化器原理(MySQL专栏启动)

&#x1f4eb;作者简介&#xff1a;小明java问道之路&#xff0c;专注于研究 Java/ Liunx内核/ C及汇编/计算机底层原理/源码&#xff0c;就职于大型金融公司后端高级工程师&#xff0c;擅长交易领域的高安全/可用/并发/性能的架构设计与演进、系统优化与稳定性建设。 &#x1…

mysql 索引优化

一、mysql索引建立原则 二、通过 EXPLAIN 分析 SQL 执行计划 可以知道以下内容&#xff1a; 假设现在我们使用 EXPLAIN 命令查看当前 SQL 是否使用了索引&#xff0c;先通过 SQL EXPLAIN 导出相应的执行计划如下&#xff1a; 下面对图示中的每一个字段进行一个说明&#x…

【MySQL】MySQL索引优化——从原理分析到实践对比

目录 使用TRACE分析MySQL优化 开启TRACE TRACE 结果集 ORDER BY & GROUP BY 优化 优化方式 分页优化 不同场景的优化方式 JOIN关联优化 算法介绍 优化方式 COUNT优化 优化方式 使用TRACE分析MySQL优化 某些情况下&#xff0c;MySQL是否走索引是不确定的[,,_,,…

MySQL索引常见面试题(2022版)

目录 为什么要建立索引&#xff1f; 哪些情况适合建立索引&#xff1f; 哪些情况下不适合建索引&#xff1f; 为什么索引是使用B树&#xff1f;&#xff08;重点&#xff09; 索引分为那几类&#xff1f; 什么是聚簇索引&#xff1f;&#xff08;重点&#xff09; 使用聚…

mysql数据库索引优化【建议收藏】

在我们程序员玩数据库的时候&#xff0c;经常会写sql&#xff0c;但是决定一个sql的好坏往往是效率&#xff0c;于是我们需要不断的去优化我们的sql&#xff0c;写一句让人称赞的sql是非常不容易的&#xff0c;也是需要大家有非常深厚的功底&#xff0c;所以优化路漫漫&#xf…

MySQL索引优化

MySQL索引优化 一、优化索引的方法二、优化步骤前缀索引优化覆盖索引优化主键索引最好是自增的索引最好设置为NOT NULL防止索引失效 总结 一、优化索引的方法 这里说一下几种常见优化索引的方法&#xff1a; 前缀索引优化&#xff1b; 覆盖索引优化&#xff1b; 主键索引最好是…

Android底层到上层的开发流程

安卓系统整体框架图如下&#xff1a; 简单总结如下&#xff1a; 1、在kernel层编写你的驱动程序&#xff1a;生成设备文件节点跟上一层传输数据&#xff0c;主要调用函数copy_to_user和copy_from_user&#xff0c;注意赋节点权限问题。 2、在HAL层封装对上提供的函数接口&…

【Android】Android底层开发实战

本书分为四个部分&#xff1a;第一部分为预备知识篇&#xff0c;简要介绍嵌入式系统的定义与软硬件开发以及Android开发环境的搭建。第二部分为系统结构篇&#xff0c;主要介绍Android系统的源码结构、内核与相关工具以及环境库。第三部分为驱动设计篇&#xff0c;主要介绍Andr…

我做了几年的Android应用层开发,为什么还要去学习安卓系统知识?

作为一个工作了好几年的Android应用层开发者&#xff0c;我准备在工作之余干一件事情&#xff0c;那就是学习Android系统知识&#xff0c;为什么要做这个决定呢&#xff1f; 其主要原因是想在Android应用层开发进阶 这个说起来并非易事&#xff0c;可能在很多人的认知里&…

一个Android应用层开发如何转型深入Android Framework?

作为一个工作了好几年的Android应用层开发者&#xff0c;准备在工作之余干一件事情&#xff0c;那就是分享一些Android系统知识&#xff0c;为什么决定要做这个呢&#xff0c;理由如下&#xff1a; 帮助更多人转型Android系统开发 不知何时起&#xff0c;单纯的Android应用层…

android底层开发-android基础架构

android architecture 在安卓中&#xff0c;最经典的架构就是分四层&#xff0c;分别是application、framework、libraries、kernel四层&#xff0c;通过这四层将android的整个架构都丰满起来 其架构图如下 android 系统组成 &#xff30;rocess FW: android 系统固件&#…

Android Framework 开发揭解密,移动开发者必须掌握的底层原理

作为过来人&#xff0c;发现很多学习者和实践者都在 Android Framework上面临着很多的困扰&#xff0c;比如&#xff1a; 工作场景中遇到难题&#xff0c;往往只能靠盲猜和感觉&#xff0c;用临时性的补救措施去掩盖&#xff0c;看似解决了问题&#xff0c;但下次同样的问题又会…

Android系统底层架构【译】

Android系统底层架构 转载请注明来源&#xff1a;http://blog.csdn.net/lifeshow 设备移植 Android提供了设备移植和支持方面有较大的自由度&#xff0c;可以制定自有的设备规范和驱动。通过硬件抽象层&#xff08;HAL-Hardware Abstraction Layer&#xff09;&#xff0c;可以…