MYSQL索引详解和优化

article/2025/11/7 5:04:21

索引的定义

我们在看书的时候,都知道有目录,我们可以通过目录快速的找到书中的内容,而书中的目录就是充当书的索引。在数据库中的索引也是一样的。

索引的定义:

索引是帮助存储引擎快速获取数据的一种数据结构,即数据目录

索引的优缺点

索引的优点:

索引最大的优点就是提高查询速度

索引的缺点:

1.  要占据物理空间

2. 创建和维护索引都需要耗时,数据量越大越耗时

3. 会降低表的增删改效率,因为每次增删改都会动态维护索引

所以索引的使用也要根据具体情况而定,一般只会在这些这段下建立索引:有唯一性限制的字段,经常在where语句出现的字段,经常在GROUP BY 和 ORDER BY 出现的字段。

而不建议建立索引的字段:

1. 不经常在where语句,GROUP BY 和 ORDER BY 语句的字段,不建索引

2. 大量重复数据的字段,不建索引

3. 表数据太少,不建索引

4. 经常更新的字段,不建索引

索引分类

数据结构分类

在MYSQL中,从数据结构进行索引分类:

B+tree索引:把所有的数据都存储在叶子结点上面,非叶子结点只存储索引,这样可以保证最少次数的IO提高索引查询的性能

Hash索引:就是根据给定的字段,进行创建Hash值。可以很快的进行单个匹配度查询,但是无法做到范围查询

Full-text索引:一个比较特殊的索引,一般用的也很少。它查找的是文本中的关键词,而不是比较索引中的值。全文索引更类似于搜索引擎做的事

但是每种存储引擎所支持的索引是不相同的,下面我们对MYSQL中的 常见存储引擎 Innodb和MyISAM进行对比:

 从对比中我们知道每一种存储引擎支持的索引类型不一定相同。而下面我们重点讲的是Innodb存储引擎中B+Tree 索引类型,也是MYSQL5.5之后的默认存储引擎。

B+Tree 索引

在创建表的时候,Innodb存储引擎会根据具体场景设计索引:

1.  有主键,那么主键做聚簇索引的key

2.  没有主键,就选择第一个不包含 NULL 值的唯一列作为聚簇索引的key

3.  以上都不符合,那就主动生成一个隐式自增 id 列作为聚簇索引的key

除了聚簇索引,其他索引都属于辅助索引,也被称为二级索引或非聚簇索引。创建的主键索引和二级索引默认使用的是 B+Tree 索引

那么 B+Tree 索引在存储是什么样子的呢?

B+Tree 是一种多叉树,叶子点才存放数据,非叶子点只存放索引,而且每个节点里的数据是按主键顺序存放的。每一层父节点的索引值都会出现在下层子节点的索引值中,因此在叶子节点中,包括了所有的索引值信息,并且每一个叶子节点都指向下一个叶子节点,形成一个链表。如下图:

主键索引 B+ Tree

 假如我们要查找主键值为30的数据,查找过程如下:

1.  将 30 与根节点的索引数据 (15,56,77) 比较,30 在 15 和 56 之间,所以根据 B+Tree的搜索逻辑,找到第二层的索引数据 (15,20,49);

2. 在第二层的索引数据  (15,20,49)中进行查找,因为 30 在 20 和 49 之间,所以找到第三层的索引数据(20, 30);

3. 在叶子节点的索引数据(20, 30)中进行查找,然后我们找到了主键值为 30 的行数据。

从例子中我们知道,我们总共走了3个节点找到数据,其实也就是说我们进行了3次I/O操作。因为所有数据(索引和数据)都是存在磁盘里的,我们没读取一个节点就会就行一次I/O操作。

而且B+Tree存储千万级别的数据也就3-4层就可以满足,也就是说查询千万级别的数据也就进行了3,4次I/O操作。所以B+Tree 相比于 B 树和二叉树来说,最大的优势在于查询效率很高,因为即使在数据量很大的情况,查询一个数据的磁盘 I/O 依然维持在 3-4次。

如果是二级索引(非聚簇索引),那是不是跟主键索引(聚簇索引)一样呢?

肯定是不一样的。它们的区别如下:

1. 聚簇索引的 B+Tree  的叶子节点存放的是实际的数据记录,而且实际的数据记录只会存在这里。

2. 非聚簇索引的 B+Tree  的叶子节点存放是主键值和索引值,没有实际数据记录。

所以说,如果要通过非聚簇索引找到一条完整的实际数据记录,那么它得也通过非聚簇索引找到叶子节点,然后获取主键值,再根据这个主键值在主键索引的B+Tree中找到对应的叶子节点,拿到完整的实际数据记录。而这个过程就是做回表,也就是进行了两次B+Tree搜索找到数据。如果我们通过非聚簇索引一次搜索就得到想要的数据结果,那么久叫做覆盖索引。下面说明非聚簇索引的过程,如下:

二级索引 B+Tree

回表

上面有两个问题:

B+Tree的3-4层高能存储千万级别的数据,怎么计算的?

详细了解的这个问题可以看这篇:

为什么 MySQL InnoDB  选择 B+tree 作为索引的数据结构?

详细了解的这个问题可以看这篇:

物理存储分类

在MYSQL中,从物理存储进行索引分类:

主键索引(聚簇索引)

二级索引(非聚簇索引/辅助索引)

这两个区别在上面有说过,区别在于叶子节点存储的数据。

字段特性分类

在MYSQL中,从字段特性进行索引分类:

主键索引

唯一索引

普通索引

前缀索引

主键索引

主键索引就是建立在主键上的索引,通常在创建表格的时候一起创建,一张表只能有一个主键,而且不能为空。

创建方法:

CREATE TABLE table_name  (

      ....

    PRIMARY KEY (index_column_1)

);

唯一索引

唯一索引就是建立在 UNIQUE 字段上的索引,一张表可以有多个唯一索引,但索引列的值必须唯一,但是允许有空值。

创建方法:

方法一:

CREATE TABLE table_name  (
  ....
  UNIQUE KEY(index_column_1,index_column_2,...) 
);

方法二:

CREATE UNIQUE INDEX index_name ON table_name(index_column_1,index_column_2,...);

普通索引

普通索引就是建立在 普通字段上的索引。

创建方法:

方法一:

CREATE TABLE table_name  (
  ....
  INDEX(index_column_1,index_column_2,...) 
);

方法二:

CREATE INDEX index_name ON table_name(index_column_1,index_column_2,...);

前缀索引

前缀索引是指对字符类型字段的前几个字符建立的索引,而不是在整个字段上建立的索引,前缀索引可以建立在字段类型为 char、 varchar、binary、varbinary 的列上。使用前缀索引的目的是为了减少索引占用的存储空间,提升查询效率.

创建方法:

方法一:

CREATE TABLE table_name  (
 column_list,
  INDEX(column_name(length))
);

方法二:

CREATE INDEX index_name ON table_name(column_name(length));

字段个数分类

在MYSQL中,从字段个数进行索引分类:

单列索引

联合索引(复合索引)

单列索引

建立在单列上的索引称为单列索引, 比如主键索引

联合索引

联合索引就是将多个字段组合成一个索引。联合索引的遵循的规则:

最左匹配原则,即按照最左优先的方式进行索引的匹配。所以建立联合索引时的字段顺序,对索引效率也有很大影响。越靠前的字段被用于索引过滤的概率越高,实际开发工作中建立联合索引时,要把区分度大的字段排在前面,这样区分度大的字段越有可能被更多的 SQL 使用到。区分度就是某个字段 column 不同值的个数「除以」表的总行数,即区分度 = distinct(columnn)/ count(*)

例如,我们有个(a,b,c)联合索引,符合联合索引的:

where a = 2;

where a = 2, b = 2;

where a = 2, b = 2, c = 2;

不符合联合索引的:

where b = 2;

where c = 2;

where b = 2, c = 2;

不符合联合索引是因为不符合最左匹配原则。

索引操作

创建索引请查看上面具体索引部分

查看索引:

SHOW INDEX FROM table_name;

删除索引:

DROP INDEX index_name ON table_name;

ALTER TABLE table_name DROP INDEX index_name;

索引优化方法

MySQL数据库优化总结中的 索引优化


http://chatgpt.dhexx.cn/article/XRlA8kPQ.shtml

相关文章

一文彻底搞懂Mysql索引优化

专属小彩蛋:前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站(前言 - 床长人工智能教程) 目录 一、索引介绍 二、性能分析 三、查询优化 四、排序优化…

MYSQL通过索引进行优化

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

MySQL索引优化(超详细)

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

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

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

【MySQL】索引优化原则

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

MySQL:索引优化、查询优化

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

Mysql-索引优化

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

MySQL索引优化总结

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

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

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

mysql 索引优化

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

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

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

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

目录 为什么要建立索引? 哪些情况适合建立索引? 哪些情况下不适合建索引? 为什么索引是使用B树?(重点) 索引分为那几类? 什么是聚簇索引?(重点) 使用聚…

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

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

MySQL索引优化

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

Android底层到上层的开发流程

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

【Android】Android底层开发实战

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

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

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

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

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

android底层开发-android基础架构

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

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

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