【Mysql】索引相关基础知识(二)

文章目录

Hash索引

底层原理 :类似于Java中的HashMap,通过键值对(索引列为键,行指针为值)存储数据。通过行指针直接定位数据。

使用场景:主要用于等值查询,查询效率极高。

优缺点:

  • 优点: hash索引只能用于等值比较(=),所以查询效率非常高
  • 缺点: 不支持范围查询,也不支持排序,因为索引列的分布是无序的

支持引擎:Memory存储引擎支持显式Hash索引,但InnoDB仅支持自适应Hash索引(无法手动控制)。

sql 复制代码
SET GLOBAL innodb_adaptive_hash_index = 1; -- 开启(默认开启)

理解: 你可以创建hash索引,但是不生效,会变成B-tree索引。

InnoDB 会根据情况(很多等值比较)自动调节为hash索引

聚簇索引与非聚集索引

按物理存储分类: InnoDB 的存储方式是聚集索引,MyISAM的存储方式是非聚集索引。

1. 聚簇索引(Clustered Index)

聚簇索引是一种存储方式,索引和数据存储在一起。每张表只能有一个聚簇索引,因为数据只能按照一种方式进行物理排序。

特点:
  1. 数据存储在索引的叶子节点: 聚簇索引的叶子节点存储了完整的行数据,因此查询索引的同时也读取了数据。
  2. 高效的单次查询: 对于基于主键的查询,由于数据和索引存储在一起,可以减少一次查询操作。
  3. 更新和删除开销较大: 由于数据存储方式与索引绑定,对数据的更新或删除需要维护索引树。
  4. InnoDB默认主键为聚簇索引: 在InnoDB引擎中,主键索引即为聚簇索引。
优缺点:
  • 优点: 查询效率高,特别是按主键查询时。
  • 缺点: 更新、插入时,维护索引树会增加系统开销;表只能有一个聚簇索引。

2. 非聚集索引(Non-Clustered Index)

非聚集索引是独立于数据存储的索引,其叶子节点存储指向实际数据的指针。

特点:
  1. 数据和索引分开存储: 非聚集索引的叶子节点存储的是主键值或数据页地址,而非行数据本身。
  2. 两次查询: 查询时需要先通过索引找到主键值或数据页地址,再通过主键回表查询完整数据(如果索引覆盖了查询字段则无需回表)。
  3. 维护成本低: 由于索引和数据分离,数据的增删改操作对索引的影响较小。
优缺点:
  • 优点: 对更新、插入友好。
  • 缺点: 查询效率比聚簇索引低,需要两次查询数据。


对比一下能更清楚的理解二者

特性 聚簇索引 非聚集索引
数据存储位置 索引的叶子节点存储行数据 索引的叶子节点存储主键值或数据页地址
查询效率 高,单次查询即可读取数据 需要两次查询,效率相对低
索引个数 每个表只能有一个 可以有多个
更新和删除效率 较低,需维护索引树 较高,索引和数据分离
应用场景 查询频繁、按主键访问 辅助查询,非主键字段条件的查询

InnoDB 的存储分2个文件; MyISAM的存储分3个文件;


二级索引

二级索引就是非聚集索引,Mysql中除主键以外的都是二级索引。

主键索引的叶子结点 是所有相关数据,二级索引的叶子节点关联的是主键。

sql 复制代码
CREATE TABLE users(
  id INT NOT NULL,
  name VARCHAR(20) NOT NULL,
  age INT NOT NULL,
  PRIMARY KEY(id)
);
新建一个以age字段的二级索引:

ALTER TABLE users ADD INDEX index_age(age);
MySQL会分别创建主键id的聚簇索引和age的二级索引:

回表与覆盖索引

回表

当非聚集索引的叶子节点无法直接满足查询需求时,需要通过主键值回到聚簇索引获取完整数据的过程称为回表。

回表查询流程:
  1. 从非聚集索引中查找目标主键值。
  2. 利用主键值到聚簇索引查找完整行数据。
  3. 返回查询结果。

ex:先找到age=35对应的id,带着id去主键索引找数据。

sql 复制代码
SELECT * FROM users WHERE age=35;
覆盖索引

当非聚集索引的叶子节点能够完全满足查询需求无需回表查询 时,就称为覆盖索引。

所以,在日常开发中,尽量不要select * ,需要什么查什么,如果出现覆盖索引的情况,查询会快很多。

ex: age这个索引列中已经包含id了,就不用回表,这样查询速度更快,性能更高。

sql 复制代码
SELECT id FROM users WHERE age=35;
优势:
  1. 减少I/O操作: 不需要回表查询完整数据。
  2. 性能提升: 查询速度更快。

单列索引与联合索引

1. 单列索引

为单个字段创建的索引。

mysql会根据单列索引字段的值进行排序,这里我假设张三排在李四前面,当索引列的值相同时,就会根据id排序,所以索引实际上已经根据索引列的值排好序了。

  • 优点: 创建简单,适合单字段的查询。
  • 缺点: 对多条件查询的优化有限。
2. 联合索引

为多个字段创建的复合索引,通常按照字段的优先级排序。

简单来说就是(name,age):先以name排序,name相同时再以age排序,如果再有其它列,依次类推,最后再以id排序。

最左前缀原则:
  1. 索引从左到右依次匹配,最左列必须出现在查询条件中才能生效。
  2. 只有连续匹配的列才会生效。

ex: (a,b,c): 查询条件只有a, ab, abc这三种组合条件,才会走联合索引。

联合索引的优点:
  1. 减少索引数量: 一个联合索引可替代多个单列索引,减少磁盘开销。
  2. 支持覆盖索引: 如果查询字段全部包含在联合索引中,可以避免回表。
  3. 筛选数据更精准: 多个条件联合过滤,提高查询效率。
使用场景:
  • 单列索引:针对单字段频繁查询,例如状态字段、布尔值字段。
  • 联合索引:针对多字段联合查询,特别是排序需求较高的场景。

总结

  1. 主键字段使用聚簇索引: 对于InnoDB表,默认主键即为聚簇索引,优先选择查询频繁的字段作为主键。

  2. 频繁查询字段加索引: 对查询频繁、过滤条件使用的字段单独加索引。

  3. 联合索引代替多单列索引: 优化查询效率时,考虑联合索引以支持覆盖索引和最左前缀匹配。

  4. 避免过多索引: 索引过多会增加插入、删除、更新的成本,且占用磁盘空间。

  5. 尽量使用覆盖索引: 避免SELECT *,只查询需要的字段。

  6. 考虑排序规则: 建表时选择合适的字符集和排序规则(如utf8mb4_general_ci)。

  7. 联合索引代替多单列索引: 优化查询效率时,考虑联合索引以支持覆盖索引和最左前缀匹配。

  8. 避免过多索引: 索引过多会增加插入、删除、更新的成本,且占用磁盘空间。

  9. 尽量使用覆盖索引: 避免SELECT *,只查询需要的字段。

  10. 考虑排序规则: 建表时选择合适的字符集和排序规则(如utf8mb4_general_ci)。

博客首页: 总是学不会.

相关推荐
huaqianzkh9 分钟前
桥接模式的理解和实践
java·设计模式·桥接模式
keep.ac10 分钟前
ArrayList源码分析、扩容机制面试题,数组和List的相互转换,ArrayList与LinkedList的区别
java·开发语言
Gin_Zou30 分钟前
通过Idea实现与gitee连接并拉取项目和上传
gitee·intellij-idea·源代码管理
西岭千秋雪_1 小时前
设计模式の装饰者&组合&外观模式
java·python·设计模式·组合模式·装饰器模式·外观模式
AI人H哥会Java1 小时前
【JAVA】Java项目实战—分布式微服务项目:分布式文件存储系统
java
程序媛徐师姐1 小时前
Java基于SpringBoot的飘香水果购物网站,附源码
java·spring boot·飘香水果购物网站·java飘香水果购物网站·飘香水果·水果购物网站
明月醉窗台1 小时前
C++ SQLite轻量化数据库使用总结
数据库·c++·sqlite
paterWang1 小时前
小程序-基于java+SSM+Vue的模拟考试管理系统设计与实现
java·vue.js·小程序
KEEPMA1 小时前
MySQL追梦旅途之性能优化
mysql·性能优化
梦.清..2 小时前
Java——多线程(中)
java·开发语言