Skip to content

slowleelab/sql-lab

Repository files navigation

SQL Lab

🐳 一套能跑、能量化对比的 MySQL + TiDB 优化实战案例集
每个案例都带真实数据,Docker 一键复现,bad/good EXPLAIN 量化对比

License: MIT MySQL TiDB CI PRs Welcome Cases

📖 在线文档https://slowleelab.github.io/sql-lab/
🤖 AI 对话:接入 DeepWiki,可直接与仓库对话提问

如果这个项目对你有帮助,欢迎 ⭐ Star 支持!你的 Star 是持续更新的动力。


✨ 为什么用这个项目

网上不缺 SQL 优化文章,但大多只讲不练——贴一段 SQL 说"这样慢,那样快",你却无法验证。

本项目不同:

特性 普通文章 SQL Lab
能否复现 ❌ 只能看 ✅ Docker 一键跑
数据量 ❌ 假数据/无数据 ✅ 百万级真实数据
效果验证 ❌ 口头说快 ✅ EXPLAIN 量化对比
版本覆盖 ❌ 不区分版本 ✅ 5.7 + 8.0 + TiDB
场景贴近 ❌ 教科书式 ✅ 生产场景命名

🚀 快速开始

# 1. 克隆
git clone https://github.com/slowleelab/sql-lab.git
cd sql-lab

# 2. 启动 MySQL(同时起 5.7 和 8.0)
docker compose up -d

# 3. 运行第一个案例
./scripts/run-case.sh 01-deep-pagination

你会看到类似这样的输出:

━━━ bad.sql (优化前) ━━━
type: ALL    rows: 980,000    Extra: Using filesort
耗时: 1230 ms

━━━ good.sql (优化后) ━━━
type: ref    rows: 12    Extra: Using index
耗时: 2 ms

🚀 扫描行数下降 99.99%,耗时下降 99.84%

📚 案例总览

102 个精选案例,覆盖 MySQL + TiDB 优化的八大核心场景:

一、索引设计与失效(18 个)

# 案例 难度 版本
01 深度分页 LIMIT 大偏移 ⭐⭐ 5.7 & 8.0
02 联合索引最左前缀失效 5.7 & 8.0
03 隐式类型转换致索引失效 ⭐⭐ 5.7 & 8.0
04 函数操作致索引失效 ⭐⭐ 5.7 & 8.0
05 LIKE 前导通配符致索引失效 5.7 & 8.0
06 OR 条件与索引合并 ⭐⭐ 5.7 & 8.0
07 范围查询后列索引失效 ⭐⭐ 5.7 & 8.0
08 覆盖索引避免回表 ⭐⭐ 5.7 & 8.0
09 索引下推 ICP(Index Condition Pushdown) ⭐⭐⭐ 5.6 & 5.7 & 8.0
10 冗余索引清理 ⭐⭐ 5.7 & 8.0
11 前缀索引优化长字符串 ⭐⭐ 5.7 & 8.0
12 索引选择性评估 ⭐⭐ 5.7 & 8.0
13 不可见索引 Invisible Index ⭐⭐ 8.0+
14 自增主键跳跃与性能 ⭐⭐ 5.7 & 8.0
15 索引合并 Index Merge 陷阱 ⭐⭐ 5.7 & 8.0
16 索引跳跃扫描 Skip Scan ⭐⭐ 8.0+
17 游标分页替代深分页 ⭐⭐ 5.7 & 8.0
18 全文索引 FULLTEXT 替代 LIKE ⭐⭐ 5.7 & 8.0

二、查询改写(14 个)

# 案例 难度 版本
19 子查询改写为 JOIN ⭐⭐ 5.7 & 8.0
20 COUNT(*) 慢查询优化 ⭐⭐ 5.7 & 8.0
21 GROUP BY filesort 优化 ⭐⭐ 5.7 & 8.0
22 大 IN 列表优化 ⭐⭐ 5.7 & 8.0
23 EXISTS vs IN 选择 ⭐⭐ 5.7 & 8.0
24 DISTINCT 优化 ⭐⭐ 5.7 & 8.0
25 NOT IN vs LEFT JOIN IS NULL ⭐⭐ 5.7 & 8.0
26 UNION vs UNION ALL 5.7 & 8.0
27 ORDER BY LIMIT 无索引优化 ⭐⭐ 5.7 & 8.0
28 HAVING 改 WHERE 提前过滤 5.7 & 8.0
29 LIMIT 1 优化 EXISTS 子查询 ⭐⭐ 5.7 & 8.0
30 时区与 TIMESTAMP vs DATETIME ⭐⭐ 5.7 & 8.0
31 时间格式使用错误与最佳实践 ⭐⭐ 5.7 & 8.0
32 SQL 反模式与正确写法量化对比 ⭐⭐ 5.7 & 8.0

三、JOIN 优化(9 个)

# 案例 难度 版本
33 JOIN 小表驱动大表 ⭐⭐ 5.7 & 8.0
34 被驱动表无索引的灾难 ⭐⭐ 5.7 & 8.0
35 Hash Join vs BNL ⭐⭐⭐ 5.7 & 8.0
36 多表 JOIN 顺序控制 ⭐⭐⭐ 5.7 & 8.0
37 自连接查询优化 ⭐⭐ 5.7 & 8.0
38 JOIN + GROUP BY 聚合优化 ⭐⭐⭐ 5.7 & 8.0
39 派生表物化优化 ⭐⭐ 5.7 & 8.0
40 STRAIGHT_JOIN 强制驱动顺序 ⭐⭐⭐ 5.7 & 8.0
41 LEFT JOIN 改 INNER JOIN 释放优化器 ⭐⭐ 5.7 & 8.0

四、DDL 与大表(10 个)

# 案例 难度 版本
42 大表加索引 Online DDL ⭐⭐⭐ 5.7 & 8.0
43 TEXT/BLOB 字段性能陷阱 ⭐⭐ 5.7 & 8.0
44 大表 DELETE 分批 ⭐⭐ 5.7 & 8.0
45 分区表 RANGE 分区优化 ⭐⭐⭐ 5.7 & 8.0
46 大表批量 INSERT 优化 ⭐⭐ 5.7 & 8.0
47 OPTIMIZE TABLE 碎片整理 ⭐⭐ 5.7 & 8.0
48 大表加列默认值 INSTANT 秒级完成 ⭐⭐ 5.7 & 8.0
49 修改字段类型的锁行为差异 ⭐⭐⭐ 5.7 & 8.0
50 大字段垂直拆表 ⭐⭐ 5.7 & 8.0
51 字段类型与长度选择最佳实践 ⭐⭐ 5.7 & 8.0

五、架构级优化(11 个)

# 案例 难度 版本
52 多条件动态筛选索引设计 ⭐⭐⭐ 5.7 & 8.0
53 报表统计汇总表 ⭐⭐ 5.7 & 8.0
54 冷热数据分离 ⭐⭐⭐ 5.7 & 8.0
55 秒杀场景库存扣减 ⭐⭐⭐ 5.7 & 8.0
56 读写分离架构 ⭐⭐⭐ 5.7 & 8.0
57 JSON 字段使用模式 ⭐⭐ 8.0+
58 软删除设计模式 ⭐⭐ 5.7 & 8.0
59 分库分表路由策略 ⭐⭐⭐ 5.7 & 8.0
60 缓存穿透与布隆过滤器 ⭐⭐⭐ 5.7 & 8.0
61 自增主键耗尽与分布式 ID ⭐⭐⭐ 5.7 & 8.0
62 连接池与 max_connections 耗尽诊断 ⭐⭐ 5.7 & 8.0

六、事务与锁(9 个)

# 案例 难度 版本
63 死锁排查与分析 ⭐⭐⭐ 5.7 & 8.0
64 间隙锁导致插入阻塞 ⭐⭐⭐ 5.7 & 8.0
65 SELECT FOR UPDATE 锁范围 ⭐⭐ 5.7 & 8.0
66 乐观锁与悲观锁对比 ⭐⭐ 5.7 & 8.0
67 幻读问题与解决 ⭐⭐⭐ 5.7 & 8.0
68 死锁重试与超时处理 ⭐⭐ 5.7 & 8.0
69 唯一索引并发插入冲突 ⭐⭐ 5.7 & 8.0
70 长事务危害 ⭐⭐ 5.7 & 8.0
71 RC vs RR 隔离级别锁行为差异 ⭐⭐⭐ 5.7 & 8.0

七、优化器与 8.0 新特性(9 个)

# 案例 难度 版本
72 降序索引消除 filesort ⭐⭐ 5.7 & 8.0
73 函数索引优化 DATE 函数查询 ⭐⭐ 8.0+
74 直方图统计优化选错索引 ⭐⭐⭐ 8.0+
75 CTE 递归查询优化树形结构 ⭐⭐ 8.0+
76 窗口函数替代相关子查询 ⭐⭐ 8.0+
77 优化器 Hint 实战 ⭐⭐ 5.7 & 8.0
78 派生条件下推优化 ⭐⭐⭐ 5.7 & 8.0
79 大批量 UPDATE 分批优化 ⭐⭐ 5.7 & 8.0
80 慢查询排查方法论 ⭐⭐⭐ 5.7 & 8.0

八、TiDB 分布式优化(22 个)

# 案例 难度 版本
81 TiDB EXPLAIN 算子树解读 ⭐⭐ TiDB
82 协处理器下推优化 ⭐⭐⭐ TiDB
83 AUTO_RANDOM 避免写热点 ⭐⭐ TiDB
84 TiDB 统计信息管理 ⭐⭐⭐ TiDB
85 TiDB 事务模型对比 ⭐⭐⭐ TiDB
86 IndexLookUp 回表与覆盖索引 ⭐⭐ TiDB
87 TiFlash 列存与 MPP 分析加速 ⭐⭐⭐ TiDB
88 TiDB GC 机制与长事务影响 ⭐⭐⭐ TiDB
89 Follower Read 读写分离 ⭐⭐ TiDB
90 TiDB 内存控制与 OOM 防护 ⭐⭐⭐ TiDB
91 TiDB Join 算法选择 ⭐⭐⭐ TiDB
92 TiDB 在线 DDL 机制 ⭐⭐ TiDB
93 TiDB Plan Cache 执行计划缓存 ⭐⭐ TiDB
94 TiDB Stale Read 历史读优化 ⭐⭐ TiDB
95 Region 热点调度与 Split 策略 ⭐⭐⭐ TiDB
96 SQL Binding 执行计划锁定 (SPM) ⭐⭐⭐ TiDB
97 TiDB 分区表优化 ⭐⭐ TiDB
98 TiDB Dashboard 诊断实战 ⭐⭐ TiDB
99 TiDB 锁机制深度解析 ⭐⭐⭐ TiDB
100 分布式 Sequence 自增方案 ⭐⭐ TiDB
101 TiDB CTE 与临时表优化 ⭐⭐ TiDB
102 TiDB Cost Model 与优化器 Hint 进阶 ⭐⭐⭐ TiDB

🛠️ 项目结构

sql-lab/
├── docs/                  # VitePress 文档站
│   ├── .vitepress/        # 配置 + 自定义组件
│   ├── guide/             # 使用指南
│   └── cases/             # 102 篇案例文档
├── sql/cases/             # 可运行 SQL(schema + seed + bad + good)
├── scripts/run-case.sh    # 一键运行案例
├── docker-compose.yml     # MySQL 5.7 + 8.0 + TiDB
├── .github/workflows/     # CI: SQL 校验 + 文档部署
└── CONTRIBUTING.md        # 贡献指南

每个案例的目录结构:

sql/cases/01-deep-pagination/
├── case.yml          # 元数据(标题/分类/难度/版本)
├── schema.sql        # 建表 + 索引
├── seed.sql          # 造数据(存储过程批量插入)
├── bad.sql           # 问题 SQL
├── good.sql          # 优化后 SQL
├── setup-good.sql    # [可选] DDL/SESSION 变更(如加索引)
└── expected/         # 参考 EXPLAIN 结果

⚙️ 运行参数

# 默认使用 MySQL 8.0
./scripts/run-case.sh 01-deep-pagination

# 指定版本
./scripts/run-case.sh 01-deep-pagination --ver 5.7
./scripts/run-case.sh 01-deep-pagination --ver 8.0

# 跳过造数据(已运行过的案例加速复跑)
./scripts/run-case.sh 01-deep-pagination --no-seed

🤝 贡献

欢迎贡献新案例!请阅读 CONTRIBUTING.md 了解如何添加一个案例。

我们特别欢迎以下方向的贡献:

  • 🏭 真实生产中遇到的优化案例(请脱敏)
  • 🆕 MySQL 8.0 新特性(CTE、窗口函数、Hash Join)的优化实践
  • 🔀 TiDB / OceanBase 等兼容数据库的差异案例
  • 📊 更多数据量级(千万级、亿级)的性能对比

📄 License

MIT

About

SQL Lab · 55 个能跑的 MySQL 优化实战案例 · Docker 一键复现 · bad/good EXPLAIN 量化对比

Topics

Resources

Contributing

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages