什么是mysql索引_mysql索引基础原理解析

1次阅读

索引是数据库查询性能的分水岭,b+树因其支持范围查询、高io效率和稳定性成为mysql默认结构;建索引需关注选择性、短字段优先及组合索引最左前缀原则。

什么是mysql索引_mysql索引基础原理解析

索引就是数据库的“目录”,不是可有可无的加速器,而是查询能否跑得动的分水岭

没有索引时,select * FROM users WHERE email = 'a@b.com' 可能要扫描几百万行;加了索引后,MySQL 直接跳到目标位置,只查 1–3 层 B+ 树节点。这不是“快一点”,而是从 O(n) 降到 O(log n)——1000 万行数据,全表扫描平均扫 500 万行,B+ 树最多查 4 次磁盘(假设扇区大小和填充率典型值)。关键在于:索引不是为“偶尔慢一下”准备的,是为“每次都要快”设计的基础设施。

为什么 B+ 树是 MySQL 默认索引结构,而不是哈希或普通二叉树

哈希索引(如 MEMORY 引擎支持)只能做等值查询(=),不支持 ORDER BYBETWEENLIKE 'abc%';普通二叉树在数据写入不均衡时会退化成链表,查询变 O(n)。而 B+ 树:

  • 所有数据都在叶子节点,且叶子节点用双向链表连起来 → 支持范围扫描和排序
  • 非叶子节点只存键值不存行数据 → 单页能放更多分支,树更矮,IO 更少
  • 每个节点填充分率通常 ≥50% → 插入/删除时分裂合并可控,稳定性强

所以 InnoDB 所有索引(包括主键)底层都是 B+ 树,连 PRIMARY KEY 本身都决定了数据物理存储顺序。

哪些字段适合建索引?别只看“WHERE 里用了”,要看选择性和过滤效率

判断一个字段值是否值得索引,核心公式是:选择性 = count(DISTINCT column) / COUNT(*)。比如:

  • email 字段选择性接近 1.0(每人邮箱基本唯一)→ 强烈推荐索引
  • status enum('active','inactive','pending') 选择性最多 0.33 → 即使出现在 WHERE 中,MySQL 也大概率放弃走索引,改用全表扫描
  • created_at 时间戳选择性高,但若常查 WHERE created_at > '2025-01-01',需确认该范围是否真的过滤掉大量数据;如果近 90% 数据都满足条件,索引收益极低

另外,短索引更优:VARCHAR(50)VARCHAR(500) 建索引更快、更省空间、缓存命中率更高——哪怕你只存 10 个字符,定义过长也会让索引页容纳更少键值,拖慢遍历速度。

组合索引怎么写才真正生效?最左前缀不是玄学,是 B+ 树搜索路径的硬约束

建了 INDEX idx_user_role_status (role, status, created_at),以下查询能用上索引:

  • WHERE role = 'admin'
  • WHERE role = 'admin' AND status = 'active'
  • WHERE role = 'admin' AND status = 'active' AND created_at > '2025-01-01'

但这些不行:

  • WHERE status = 'active'(跳过最左列 role,无法定位子树)
  • WHERE role = 'admin' AND created_at > '2025-01-01'(中间缺失 statuscreated_at 无法利用有序性)

真正容易被忽略的是:如果经常按 status 单独查,又需要 role + status 联合查,不要盲目建两个单列索引——优先建 (status, role) 组合索引,再看执行计划是否覆盖全部场景;否则多索引会吃磁盘、拖慢写入,还可能让优化器选错索引。

索引不是建得越多越好,也不是建了就自动生效;它依赖你对查询模式、数据分布和 B+ 树工作方式的真实理解。一个没被 EXPLAIN 验证过的索引,和没建一样。

text=ZqhQzanResources