当前位置: 首页 > news >正文

MySQL索引解析

文章目录

  • 为什么需要索引?
  • MySQL索引的底层结构
  • 索引的分类
    • 按数据结构分类
    • 按物理存储分类
    • 按字段数量分类
  • 联合索引与最左前缀原则
  • 索引失效的常见场景
    • 1. 函数操作
    • 2. 类型转换
    • 3. 模糊查询
    • 4. 范围查询影响后续字段
    • 5. 使用OR连接
  • 索引设计原则
  • 注意事项
    • 1. 不是索引越多越好
    • 2. 小表不一定需要索引
    • 3. 联合索引的字段顺序很重要
    • 4. 注意索引的维护成本
  • 总结

为什么需要索引?

数据库索引就像是给数据表建立的"目录",帮助数据库快速定位到需要的数据行。没有索引的查询过程,查询数据走的是全表扫描。有了索引之后,数据库可以通过索引结构快速定位到目标数据,大大减少了需要检查的数据量。

MySQL索引的底层结构

MySQL的InnoDB存储引擎主要使用B+树作为索引结构,其优点如下:

  1. 磁盘友好:B+树的节点可以存储更多的键值,减少了树的高度,也就减少了磁盘I/O次数
  2. 范围查询高效:叶子节点通过指针连接,形成有序链表,范围查询只需要在叶子层遍历
  3. 稳定的查询性能:所有数据都在叶子节点,查询效率稳定

索引的分类

按数据结构分类

1. B+树索引
最常见的索引类型,适用于大部分查询场景。

2. Hash索引
基于哈希表实现,等值查询速度极快,但不支持范围查询。

3. 全文索引
专门用于文本搜索,支持关键词匹配。

按物理存储分类

1. 聚簇索引(主键索引)
数据行直接存储在索引的叶子节点中,每个表只能有一个聚簇索引。

2. 非聚簇索引(二级索引)
叶子节点存储的是主键值,需要回表查询获取完整数据。

-- 创建表时的聚簇索引
CREATE TABLE user (id INT PRIMARY KEY,  -- 聚簇索引name VARCHAR(50),email VARCHAR(100),INDEX idx_name(name)  -- 非聚簇索引
);

按字段数量分类

1. 单列索引

CREATE INDEX idx_name ON user(name);

2. 复合索引(联合索引)

CREATE INDEX idx_name_age ON user(name, age);

联合索引与最左前缀原则

复合索引是实际开发中经常用到的优化手段,但需要理解最左前缀原则。

-- 创建复合索引
CREATE INDEX idx_name_age_city ON user(name, age, city);

这个索引实际上相当于创建了三个索引:

  • (name)
  • (name, age)
  • (name, age, city)

能用到索引的查询:

SELECT * FROM user WHERE name = '张三';  
SELECT * FROM user WHERE name = '张三' AND age = 25; 
SELECT * FROM user WHERE name = '张三' AND age = 25 AND city = '北京'; 
SELECT * FROM user WHERE name = '张三' AND city = '北京'; 

不能用到索引的查询:

SELECT * FROM user WHERE age = 25; 
SELECT * FROM user WHERE city = '北京'; 
SELECT * FROM user WHERE age = 25 AND city = '北京'; 

索引失效的常见场景

在实际开发中,经常会遇到明明创建了索引,但查询还是很慢的情况。以下是一些常见的索引失效场景:

1. 函数操作

-- 索引失效
SELECT * FROM user WHERE YEAR(create_time) = 2023;

2. 类型转换

-- phone字段是VARCHAR类型,索引失效
SELECT * FROM user WHERE phone = 13800138000;-- 正确写法
SELECT * FROM user WHERE phone = '13800138000';

3. 模糊查询

-- 索引失效
SELECT * FROM user WHERE name LIKE '%张%';-- 可以使用索引
SELECT * FROM user WHERE name LIKE '张%';

4. 范围查询影响后续字段

-- 对于复合索引 (name, age, city)
-- age使用了范围查询,city字段的索引会失效
SELECT * FROM user WHERE name = '张三' AND age > 20 AND city = '北京';

5. 使用OR连接

-- 如果OR两边的字段都有索引才能使用索引
SELECT * FROM user WHERE name = '张三' OR email = 'zhangsan@email.com';

索引设计原则

  • 选择性高的字段:重复值少的字段更适合创建索引
  • 频繁查询的字段:WHERE、ORDER BY、GROUP BY中经常出现的字段
  • 小的数据类型:使用更小的数据类型可以减少索引空间

注意事项

1. 不是索引越多越好

每个索引都会占用存储空间,增加写操作的开销。

2. 小表不一定需要索引

对于数据量很小的表(几百条记录),全表扫描可能比索引查询更快。

3. 联合索引的字段顺序很重要

根据查询条件的使用频率和选择性来决定字段顺序。

4. 注意索引的维护成本

频繁的INSERT、UPDATE、DELETE操作会影响索引性能,需要权衡查询性能和写入性能。

总结

索引是数据库性能优化的重要手段,但也不是万能的。要掌握最左前缀原则,合理设计复合索引,避免常见的索引失效场景,在优化方面通过EXPLAIN分析执行计划。

http://www.dtcms.com/a/311518.html

相关文章:

  • vue3pinia
  • Corrosion2靶机
  • Cyber Weekly #63
  • 搜索引擎评估革命:用户行为模型如何颠覆传统指标?
  • Sklearn 机器学习 数据聚类 用Numpy自己实现聚类
  • 【C++】类和对象(2)
  • 使用keil点亮stc8核心板的灯
  • 逻辑回归 银行贷款资格判断案列优化 交叉验证,调整阈值,下采样与过采样方法
  • MQTT 入门教程:MQTT工具调式
  • 堆----2.前 K 个高频元素
  • VirtualBox 的 HOST 键(主机键)是 右Ctrl 键(即键盘右侧的 Ctrl 键)笔记250802
  • 学习笔记:无锁队列的原理以及c++实现
  • Linux 高级 I/O 系统调用详解
  • Vue 响应式基础全解析2
  • Node.js中path模块的使用指南
  • InfluxDB 与 Node.js 框架:Express 集成方案(二)
  • 如何在`<link type=“icon“ href=`的`href`中写SVG并使用path标签? 笔记250802
  • 嵌入式 C 语言入门:递归与变量作用域学习笔记 —— 从概念到内存特性
  • 深入 Go 底层原理(十三):interface 的内部表示与动态派发
  • Javaweb————Apache Tomcat服务器介绍及Windows,Linux,MAC三种系统搭建Apache Tomcat
  • 技术文章:覆铜板的阻燃性
  • UniappDay07
  • 【AI】AIService(基本使用与指令定制)
  • cv快速input
  • 【云计算】云主机的亲和性策略(三):云主机 宿主机
  • Springboot原理和Maven高级
  • 操作系统:远程过程调用( Remote Procedure Call,RPC)
  • MQTT 入门教程:三步从 Docker 部署到 Java 客户端实现
  • Linux基础学习笔记二
  • MySQL PostgreSQL JDBC URL 配置允许批量操作