news 2026/8/7 7:07:30

不懂数据库索引原理?你写的SQL跑的慢如老牛,就等着挨骂吧

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
不懂数据库索引原理?你写的SQL跑的慢如老牛,就等着挨骂吧

一、索引底层原理:B+树是如何吊打其他数据结构的?

1.1 为什么不用哈希表?

  • 哈希索引:精确查询O(1),但范围查询、排序操作直接崩盘
  • B+树:平衡多路搜索树,保证查询、范围、排序全能打

1.2 B+树核心设计

  • 非叶子节点只存键值,大幅降低树高度(1000万数据只需3~4层)
  • 叶子节点双向链表链接,范围查询如丝般顺滑
  • 所有数据存于叶子节点,查询稳定性极强(任何查询IO次数相同)

1.3 磁盘IO才是瓶颈

  • 机械磁盘随机IO:10ms/次
  • B+树10M数据:3次IO → 30ms
  • 全表扫描:10000次IO → 100秒
  • 性能差3000倍以上!

二、索引四大使用原则:违反一条性能血崩!

2.1 最左前缀原则

  • 索引(a, b, c)
  • ✅ 能用:a=?a=? and b=?a=? and b=? and c=?
  • ❌ 不能用:b=?c=?b=? and c=?
  • 原理:B+树按索引定义顺序构建,跳字段如同查字典跳过拼音首字母

2.2 避免索引失效

  • ❌ 对索引列计算:WHERE age+1>20
  • ❌ 前导模糊匹配:WHERE name LIKE '%张'
  • ❌ 隐式类型转换:WHERE varchar_col=123(应写’123’)
  • ❌ OR一侧无索引:WHERE a=1 OR b=2(若b无索引,全表扫描)

2.3 索引选择性原则

  • 公式:索引选择性 = 不重复值数量 / 总记录数
  • 性别(男/女):选择性≈0.5 →不值得单独建索引
  • 手机号:选择性≈0.99 →极品索引字段
  • 技巧:低选择性字段可搭配高选择性字段建联合索引

2.4 覆盖索引优先

  • SELECT *→ 大概率回表查询
  • SELECT 索引包含字段→ 无需回表,性能翻倍
  • 效果:减少50%磁盘IO,速度提升100%

三、六大优化实战:从青铜到王者的秘诀

3.1 EXPLAIN命令必看字段

  • type:至少达到ref(索引访问),杜绝ALL(全表扫描)
  • key:确认实际使用的索引
  • rows:预估扫描行数(超过1000需优化)
  • Extra:杜绝Using filesortUsing temporary

3.2 联合索引优化技巧

  • 场景:查询WHERE a=? and b=?,排序ORDER BY c
  • 方案:建(a, b, c),同时优化查询和排序
  • 原理:B+树叶子节点按索引排序,避免额外排序操作

3.3 大数据分页优化

  • LIMIT 100000,20:先扫描100020行,再丢100000行

  • 子查询优化

    SELECT * FROM table
    INNER JOIN (
    SELECT id FROM table
    WHERE condition
    ORDER BY index_field
    LIMIT 100000,20
    ) AS tmp USING(id)

  • 效果:100ms → 2ms,提升50倍

3.4 索引碎片定期维护

  • 频繁增删导致索引碎片增多,性能下降
  • 每月执行ALTER TABLE table REBUILD INDEX index_name

3.5 杜绝过度索引

  • 每个索引:写操作变慢 + 占用磁盘

  • 排查无用索引

    SELECT * FROM sys.schema_unused_indexes;

  • 维护成本:索引数不宜超过表字段数的30%

3.6 热点数据分离

  • 超大表(十亿级)采用分区表+局部索引
  • 冷热数据分离:热数据索引内存加载,冷数据索引磁盘存放

四、血泪案例:这些坑踩过才知道痛

4.1 隐式转换灾难

  • 字段:phone VARCHAR(20)
  • 错误:WHERE phone = 13800138000(未加引号)
  • 结果:索引失效,全表扫描,数据库CPU100%持续2小时

4.2 联合索引顺序错误

  • 索引:(age, city)
  • 查询:WHERE city='北京' AND age>25
  • 结果:仅能用到age索引,city条件依旧全表扫描

4.3 OR条件未优化

  • 查询:WHERE a=1 OR b=2

  • 错误:仅a有索引

  • 优化:改为UNION ALL

    SELECT * FROM table WHERE a=1
    UNION ALL
    SELECT * FROM table WHERE b=2

  • 效果:5秒 → 0.1秒


结语:索引玩得溜,升职加薪快!

  • 初级程序员:疯狂写SQL
  • 高级程序员:疯狂优化SQL
  • 架构师:设计让SQL跑得快的库表结构

现在行动起来

  1. 打开慢查询日志
  2. 用EXPLAIN分析每个慢查询
  3. 遵循索引四大原则
  4. 定期监控索引使用情况

数据库不会说谎,性能说明一切!

PS:在评论区说出你被索引坑得最惨的一次经历,点赞送《分布式索引设计精髓》电子书!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/7 23:53:03

【课程设计/毕业设计】基于Spring Boot框架的汽车配件销售管理系统基于JavaWeb的汽配销售管理系统【附源码、数据库、万字文档】

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

作者头像 李华
网站建设 2026/8/7 22:55:02

深度剖析Dify PDF解密失败根源(附完整错误代码对照表)

第一章:深度剖析Dify PDF解密失败根源(附完整错误代码对照表)在使用 Dify 平台处理加密 PDF 文件时,用户频繁遭遇解密失败问题。该现象通常由加密算法不兼容、权限配置缺失或元数据校验异常引发。深入分析底层日志可发现&#xff…

作者头像 李华
网站建设 2026/8/7 22:57:08

只需5个步骤带你了解渗透测试全过程,SSH端口22如何完全沦陷!

前言:为什么 SSH 攻击值得关注? SSH(Secure Shell)是一种用于在不安全网络上建立安全连接的协议,主要用于远程服务器管理。由于 SSH 端口 22 通常默认开放,且广泛用于服务器管理,因此它成为攻击…

作者头像 李华