CSNotesCSNotes
TODO
数据库
Java
SSM
React
学习路线
分布式
Redis
实用工具
GitHub
TODO
数据库
Java
SSM
React
学习路线
分布式
Redis
实用工具
GitHub
  • 第一阶段 SQL 语法与使用

    • 一、MySQL 语法基础
    • 二、多表查询与笛卡尔积
    • 三、JOIN 类型与算法
    • 四、LIKE 通配符与正则
    • 五、GROUP BY/HAVING /窗口函数
    • 六、字段类型与选型
    • 七、约束、主键与 DDL 语法
  • 第二阶段 SQL 执行与优化

    • 一、一条建表语句是如何执行的?
    • 二、EXPLAIN 执行计划
  • 第三阶段 数据存储结构(MyDB 轮子核心)

    • 一、字符集与 CHAR/VARCHAR 存储
    • 二、最大行大小 65535 bytes
    • 三、为什么 VARCHAR 上限是 16383?
    • 四、表、页与 Page Header 概念
    • 五、InnoDB 行格式 COMPACT
    • 六、磁盘空间管理器
  • 第四阶段 索引与数据结构

    • 一、为什么是 B+ 树?
    • 二、B+ 树插入、分裂、合并的完整过程
    • 三、容量计算:一颗高度为 3 的 B+ 树能存多少条数据?
    • 四、索引分类(聚簇/二级/联合/覆盖)
    • 五、联合索引 + 最左匹配原则
    • 六、索引失效 7 大场景
    • 七、索引创建策略:三星索引法
  • 第五阶段 事务、MVCC 与并发控制

    • 一、事务
    • 二、事务的本质(内核视角)
    • 三、MVCC 多版本快照读
    • 四、死锁四条件
    • 五、一条 INSERT 语句背后在干吗?
  • 第六阶段 预写日志 WAL 与崩溃恢复

    • 一、预写日志 WAL(Redo/Undo)
  • 第七阶段 数据建模与范式

    • 一、数据建模范式(入门版)
    • 二、数据建模范式(进阶版)
  • 第八阶段 数据库概念全景

    • 一、数据库/DBMS/SQL 全景定义
  • 第九阶段 常见面试题专题(占位:待补)

五、联合索引 + 最左匹配原则

(一)为什么使用联合索引?

  • 减少开销。创建一个联合索引 (col1,col2,col3),实际相当于建了 (col1),(col1,col2)

,(col1,col2,col3) 三个索引。每多一个索引,都会增加写操作的开销和磁盘空间的开销。对于大量数据的表,使用联合索引会大大减少开销。

  • 覆盖索引。对联合索引 (col1,col2,col3),如果有如下 SQL:select col1,col2,col3 from test where col1=1 and col2=2;那么 MySQL 可以直接通过遍历
  • 效率高。索引列越多,通过索引筛选出的数据越少。有 1000w 条数据的表。有如下的 SQL:select * from table where col1=1 and col2=2 and col3=3;,假设每个条件可以筛选出 10% 的数据,如果只有单值索引,那么通过索引筛选出$1000w10%=100w$条数据,再回表从 100w 条数据中找到符合 col2=2 and col3=3 的数据,然后再排序,分页;如果是联合索引,通过索引筛选出 $1000w10%*10%*10%=1w$

(二)隐式转换

什么是隐式转换?

image-20250528204529485
image-20250528204529485
image-20250528204624873
image-20250528204624873

运行 select '10'>9;返回 1

运行 select '10'>'9';返回 0

这就是隐式转换规则,对于不同类型的值比较,会把字符串转换为数字

create table db.test(
id BIGINT auto_increment PRIMARY key,
name varchar(30),
create_time TIMESTAMP(6),
update_time TIMESTAMP(6) on UPDATE CURRENT_TIMESTAMP(6)
);
create index idx_name on db.test(name);
image-20250528215731506
image-20250528215731506

select * from test where name = 1 不走索引

image-20250528215818353
image-20250528215818353

select * from test where name = '1' 走索引

等价于 select * from test where name = cast('1' as signed int);

这是因为 MySQL 在遇到字符串和数字比较时,会把字符串转换为数字。

select _ from test where name = 1; 等价于 select _ from test where cast(name as signed int)=1;

(三)对索引使用函数

image-20250528230857671
image-20250528230857671

select * from test where length(name)=2;

对索引使用函数不走索引。

因为索引保存的是索引字段的原始值,而不是经过函数计算后的值。

(四)WHERE 子句中的 OR

image-20250528234532318
image-20250528234532318

因为 OR 的含义是两个条件满足一个即可,所以只有一个条件列是索引列是没意义的

编辑此页
上次更新: 2026/9/18 20:24
Prev
四、索引分类(聚簇/二级/联合/覆盖)
Next
六、索引失效 7 大场景