Skip to content

Commit 8558f32

Browse files
committed
feat: 加入 TiDB 全面支持,新增 6 个 TiDB 分布式优化案例 (v1.7.0)
基础设施: - docker-compose.yml 新增 TiDB 集群(PD + TiKV + TiDB 三容器,端口 4000) - run-case.sh 新增 --ver tidb 支持 - validate-sql.yml CI 矩阵新增 TiDB 验证 新增分类「八、TiDB 分布式优化」6 个案例: - 81 · TiDB EXPLAIN 算子树解读 — MySQL vs TiDB EXPLAIN 对照 - 82 · 协处理器下推优化 — cop[tikv] vs root task - 83 · AUTO_RANDOM 避免写热点 — 分布式 ID 消除单 Region 瓶颈 - 84 · TiDB 统计信息管理 — ANALYZE / 健康度 / stale stats - 85 · TiDB 事务模型对比 — 乐观事务 vs 悲观事务 - 86 · IndexLookUp 回表与覆盖索引 — Build→Probe 两阶段 文档更新: - config.ts / HomeFeatures.vue / README / cases/index 同步更新 - 首页统计: 7→8 场景, 80→86 案例 - new-case.sh 脚手架支持 tidb 分类
1 parent 09885b0 commit 8558f32

61 files changed

Lines changed: 3980 additions & 41 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/validate-sql.yml

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,43 +2,68 @@ name: 验证 SQL 案例
22
on:
33
push:
44
branches: [main, master]
5-
paths: ['sql/**', 'scripts/**']
5+
paths: ['sql/**', 'scripts/**', 'docker-compose.yml']
66
pull_request:
7-
paths: ['sql/**', 'scripts/**']
7+
paths: ['sql/**', 'scripts/**', 'docker-compose.yml']
88

99
jobs:
1010
validate:
1111
runs-on: ubuntu-latest
1212
strategy:
13+
fail-fast: false
1314
matrix:
14-
mysql-version: ['5.7', '8.0']
15+
mysql-version: ['5.7', '8.0', 'tidb']
1516
steps:
1617
- uses: actions/checkout@v4
1718

18-
- name: 启动 MySQL ${{ matrix.mysql-version }}
19+
- name: 启动 ${{ matrix.mysql-version == 'tidb' && 'TiDB 集群' || format('MySQL {0}', matrix.mysql-version) }}
1920
run: |
2021
if [[ "${{ matrix.mysql-version }}" == "5.7" ]]; then
2122
docker compose up -d mysql57
2223
PORT=3307
23-
else
24+
for i in $(seq 1 60); do
25+
docker exec sql-treasure-mysql57 mysqladmin ping -h localhost -proot &>/dev/null && break
26+
sleep 2
27+
done
28+
elif [[ "${{ matrix.mysql-version }}" == "8.0" ]]; then
2429
docker compose up -d mysql80
2530
PORT=3308
31+
for i in $(seq 1 60); do
32+
docker exec sql-treasure-mysql80 mysqladmin ping -h localhost -proot &>/dev/null && break
33+
sleep 2
34+
done
35+
else
36+
# TiDB: 启动整个集群(pd → tikv → tidb)
37+
docker compose up -d pd tikv tidb
38+
# 等待 TiDB SQL 层就绪(从宿主机通过 4000 端口连接)
39+
echo "等待 TiDB 集群就绪..."
40+
for i in $(seq 1 120); do
41+
if mysql -h 127.0.0.1 -P 4000 -uroot -e "SELECT 1" &>/dev/null; then
42+
echo "TiDB 已就绪"
43+
break
44+
fi
45+
[[ $i -eq 120 ]] && { echo "::error::TiDB 启动超时"; docker compose logs tidb; exit 1; }
46+
sleep 2
47+
done
2648
fi
27-
# 等待就绪
28-
for i in $(seq 1 60); do
29-
docker exec sql-treasure-mysql$(echo ${{ matrix.mysql-version }} | tr -d '.') mysqladmin ping -h localhost -proot &>/dev/null && break
30-
sleep 2
31-
done
3249
3350
- name: 验证所有案例的 SQL 语法
3451
run: |
35-
PORT=$( [[ "${{ matrix.mysql-version }}" == "5.7" ]] && echo 3307 || echo 3308 )
3652
FAIL=0
3753
for case_dir in sql/cases/*/; do
3854
case_name=$(basename "$case_dir")
39-
echo "::group::验证案例: $case_name (MySQL ${{ matrix.mysql-version }})"
55+
56+
# TiDB 只验证专属案例(编号 81+)
57+
if [[ "${{ matrix.mysql-version }}" == "tidb" ]]; then
58+
case_num=$(echo "$case_name" | grep -o '^[0-9]*')
59+
if [[ -z "$case_num" || "$case_num" -lt 81 ]]; then
60+
continue
61+
fi
62+
fi
63+
64+
echo "::group::验证案例: $case_name (${{ matrix.mysql-version }})"
4065
if ! ./scripts/run-case.sh "$case_name" --ver ${{ matrix.mysql-version }}; then
41-
echo "::error::案例 $case_name 在 MySQL ${{ matrix.mysql-version }} 上运行失败"
66+
echo "::error::案例 $case_name 在 ${{ matrix.mysql-version }} 上运行失败"
4267
FAIL=1
4368
fi
4469
echo "::endgroup::"

CHANGELOG.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,28 @@
11
# 更新日志
22

3+
## v1.7.0 (2026-07-28)
4+
5+
### 新增
6+
7+
- **加入 TiDB 全面支持**,案例总数从 80 增至 86
8+
- **新增分类「八、TiDB 分布式优化」**(6 个案例):
9+
- 81 · TiDB EXPLAIN 算子树解读 — 从 MySQL EXPLAIN 到 TiDB 树形算子的过渡指南
10+
- 82 · 协处理器下推优化 — cop[tikv] vs root task 的执行位置差异
11+
- 83 · AUTO_RANDOM 避免写热点 — 分布式 ID 替代 AUTO_INCREMENT 消除单 Region 写入瓶颈
12+
- 84 · TiDB 统计信息管理 — ANALYZE、健康度、stale stats 导致选错索引
13+
- 85 · TiDB 事务模型对比 — 乐观事务 vs 悲观事务、TSO、AS OF TIMESTAMP
14+
- 86 · IndexLookUp 回表与覆盖索引 — Build→Probe 两阶段 vs IndexReader 覆盖索引
15+
- **基础设施**
16+
- docker-compose.yml 新增 TiDB 集群(PD + TiKV + TiDB 三容器,端口 4000)
17+
- run-case.sh 新增 `--ver tidb` 支持
18+
- CI 矩阵新增 TiDB 验证
19+
20+
### 变更
21+
22+
- README 新增 TiDB 徽章和案例表格
23+
- 首页统计更新:7→8 场景,80→86 案例
24+
- sidebar、cases/index.md、introduction 同步更新
25+
326
## v1.6.0 (2026-07-28)
427

528
### 重构

README.md

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
# SQL Lab
22

3-
> 🐳 一套**能跑、能量化对比**的 MySQL 优化实战案例集
3+
> 🐳 一套**能跑、能量化对比**的 MySQL + TiDB 优化实战案例集
44
> 每个案例都带真实数据,Docker 一键复现,bad/good EXPLAIN 量化对比
55
66
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
77
[![MySQL](https://img.shields.io/badge/MySQL-5.7%20%7C%208.0-blue.svg)](https://www.mysql.com/)
8+
[![TiDB](https://img.shields.io/badge/TiDB-v7.5.1-purple.svg)](https://pingcap.com/)
89
[![CI](https://github.com/slowleelab/sql-lab/actions/workflows/validate-sql.yml/badge.svg)](https://github.com/slowleelab/sql-lab/actions)
910
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](CONTRIBUTING.md)
10-
[![Cases](https://img.shields.io/badge/cases-80-orange.svg)](docs/cases/)
11+
[![Cases](https://img.shields.io/badge/cases-86-orange.svg)](docs/cases/)
1112

1213
📖 **在线文档**[https://slowleelab.github.io/sql-lab/](https://slowleelab.github.io/sql-lab/)
1314
🤖 **AI 对话**:接入 DeepWiki,可直接与仓库对话提问
@@ -27,7 +28,7 @@
2728
| 能否复现 | ❌ 只能看 | ✅ Docker 一键跑 |
2829
| 数据量 | ❌ 假数据/无数据 | ✅ 百万级真实数据 |
2930
| 效果验证 | ❌ 口头说快 | ✅ EXPLAIN 量化对比 |
30-
| 版本覆盖 | ❌ 不区分版本 | ✅ 5.7 + 8.0 双版本 |
31+
| 版本覆盖 | ❌ 不区分版本 | ✅ 5.7 + 8.0 + TiDB |
3132
| 场景贴近 | ❌ 教科书式 | ✅ 生产场景命名 |
3233

3334
## 🚀 快速开始
@@ -60,7 +61,7 @@ type: ref rows: 12 Extra: Using index
6061

6162
## 📚 案例总览
6263

63-
**80 个精选案例**,覆盖 MySQL 优化的七大核心场景
64+
**86 个精选案例**,覆盖 MySQL + TiDB 优化的八大核心场景
6465

6566
### 一、索引设计与失效(18 个)
6667
| # | 案例 | 难度 | 版本 |
@@ -169,17 +170,28 @@ type: ref rows: 12 Extra: Using index
169170
| 78 | [派生条件下推优化](docs/cases/optimizer/78-derived-condition-pushdown.md) | ⭐⭐⭐ | 5.7 & 8.0 |
170171
| 79 | [大批量 UPDATE 分批优化](docs/cases/optimizer/79-batch-update.md) | ⭐⭐ | 5.7 & 8.0 |
171172
| 80 | [慢查询排查方法论](docs/cases/optimizer/80-slow-query-diagnosis.md) | ⭐⭐⭐ | 5.7 & 8.0 |
173+
174+
### 八、TiDB 分布式优化(6 个)
175+
| # | 案例 | 难度 | 版本 |
176+
|---|------|------|------|
177+
| 81 | [TiDB EXPLAIN 算子树解读](docs/cases/tidb/81-tidb-explain-tree.md) | ⭐⭐ | TiDB |
178+
| 82 | [协处理器下推优化](docs/cases/tidb/82-coprocessor-pushdown.md) | ⭐⭐⭐ | TiDB |
179+
| 83 | [AUTO_RANDOM 避免写热点](docs/cases/tidb/83-auto-random.md) | ⭐⭐ | TiDB |
180+
| 84 | [TiDB 统计信息管理](docs/cases/tidb/84-tidb-statistics.md) | ⭐⭐⭐ | TiDB |
181+
| 85 | [TiDB 事务模型对比](docs/cases/tidb/85-tidb-transaction.md) | ⭐⭐⭐ | TiDB |
182+
| 86 | [IndexLookUp 回表与覆盖索引](docs/cases/tidb/86-index-lookup.md) | ⭐⭐ | TiDB |
183+
172184
## 🛠️ 项目结构
173185

174186
```
175187
sql-lab/
176188
├── docs/ # VitePress 文档站
177189
│ ├── .vitepress/ # 配置 + 自定义组件
178190
│ ├── guide/ # 使用指南
179-
│ └── cases/ # 80 篇案例文档
191+
│ └── cases/ # 86 篇案例文档
180192
├── sql/cases/ # 可运行 SQL(schema + seed + bad + good)
181193
├── scripts/run-case.sh # 一键运行案例
182-
├── docker-compose.yml # MySQL 5.7 + 8.0
194+
├── docker-compose.yml # MySQL 5.7 + 8.0 + TiDB
183195
├── .github/workflows/ # CI: SQL 校验 + 文档部署
184196
└── CONTRIBUTING.md # 贡献指南
185197
```

docker-compose.yml

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,60 @@ services:
4040
volumes:
4141
- mysql80_data:/var/lib/mysql
4242

43+
# ─────────── TiDB 集群(分布式 SQL)───────────
44+
# PD 调度节点(元数据管理 + 时间戳分配)
45+
pd:
46+
image: pingcap/pd:v7.5.1
47+
container_name: sql-treasure-pd
48+
restart: on-failure
49+
ports:
50+
- "2379:2379"
51+
- "2380:2380"
52+
volumes:
53+
- pd_data:/var/lib/pd
54+
command:
55+
- --name=pd
56+
- --data-dir=/var/lib/pd
57+
- --client-urls=http://0.0.0.0:2379
58+
- --peer-urls=http://0.0.0.0:2380
59+
- --advertise-client-urls=http://pd:2379
60+
- --advertise-peer-urls=http://pd:2380
61+
- --initial-cluster=pd=http://pd:2380
62+
63+
# TiKV 存储节点(RocksDB 持久化 + Raft 共识)
64+
tikv:
65+
image: pingcap/tikv:v7.5.1
66+
container_name: sql-treasure-tikv
67+
restart: on-failure
68+
ports:
69+
- "20160:20160"
70+
volumes:
71+
- tikv_data:/var/lib/tikv
72+
command:
73+
- --addr=0.0.0.0:20160
74+
- --advertise-addr=tikv:20160
75+
- --data-dir=/var/lib/tikv
76+
- --pd=pd:2379
77+
depends_on:
78+
- pd
79+
80+
# TiDB SQL 计算节点(MySQL 协议兼容,端口 4000)
81+
tidb:
82+
image: pingcap/tidb:v7.5.1
83+
container_name: sql-treasure-tidb
84+
restart: on-failure
85+
ports:
86+
- "4000:4000"
87+
- "10080:10080"
88+
command:
89+
- --store=tikv
90+
- --path=pd:2379
91+
- --advertise-address=tidb
92+
depends_on:
93+
- tikv
94+
4395
volumes:
4496
mysql57_data:
4597
mysql80_data:
98+
pd_data:
99+
tikv_data:

docs/.vitepress/config.ts

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -142,13 +142,25 @@ const sidebar = {
142142
{ text: '80 · 慢查询排查方法论', link: '/cases/optimizer/80-slow-query-diagnosis' },
143143
],
144144
},
145+
{
146+
text: '八、TiDB 分布式优化',
147+
collapsed: false,
148+
items: [
149+
{ text: '81 · TiDB EXPLAIN 算子树解读', link: '/cases/tidb/81-tidb-explain-tree' },
150+
{ text: '82 · 协处理器下推优化', link: '/cases/tidb/82-coprocessor-pushdown' },
151+
{ text: '83 · AUTO_RANDOM 避免写热点', link: '/cases/tidb/83-auto-random' },
152+
{ text: '84 · TiDB 统计信息管理', link: '/cases/tidb/84-tidb-statistics' },
153+
{ text: '85 · TiDB 事务模型对比', link: '/cases/tidb/85-tidb-transaction' },
154+
{ text: '86 · IndexLookUp 回表与覆盖索引', link: '/cases/tidb/86-index-lookup' },
155+
],
156+
},
145157
],
146158
}
147159

148160
// ────────────────────────────── 站点配置 ──────────────────────────────
149161
export default defineConfig({
150162
title: 'SQL Lab',
151-
description: '一套能跑、能量化对比的 MySQL 优化实战案例集',
163+
description: '一套能跑、能量化对比的 MySQL + TiDB 优化实战案例集',
152164
lang: 'zh-CN',
153165
lastUpdated: true,
154166
cleanUrls: true,
@@ -166,19 +178,19 @@ export default defineConfig({
166178
['link', { rel: 'icon', href: '/sql-lab/favicon.svg' }],
167179

168180
// SEO: 关键词
169-
['meta', { name: 'keywords', content: 'MySQL优化,SQL优化,EXPLAIN,索引优化,MySQL 8.0,数据库性能,Docker,慢查询,事务锁,查询改写' }],
181+
['meta', { name: 'keywords', content: 'MySQL优化,SQL优化,EXPLAIN,索引优化,MySQL 8.0,数据库性能,Docker,慢查询,事务锁,查询改写,TiDB,分布式数据库,NewSQL,TiKV,coprocessor' }],
170182

171183
// Open Graph(社交分享卡片)
172184
['meta', { property: 'og:site_name', content: 'SQL Lab' }],
173185
['meta', { property: 'og:type', content: 'website' }],
174-
['meta', { property: 'og:title', content: 'SQL Lab · 80 个能跑的 MySQL 优化实战案例' }],
175-
['meta', { property: 'og:description', content: '一套能跑、能量化对比的 MySQL 优化实战案例集。80 个精选案例,7 大场景,Docker 一键复现,bad/good EXPLAIN 量化对比。' }],
186+
['meta', { property: 'og:title', content: 'SQL Lab · 86 个能跑的 MySQL/TiDB 优化实战案例' }],
187+
['meta', { property: 'og:description', content: '一套能跑、能量化对比的 MySQL 优化实战案例集。86 个精选案例,8 大场景,覆盖 MySQL 5.7/8.0 和 TiDB,Docker 一键复现,bad/good EXPLAIN 量化对比。' }],
176188
['meta', { property: 'og:url', content: 'https://slowleelab.github.io/sql-lab/' }],
177189
['meta', { property: 'og:image', content: 'https://slowleelab.github.io/sql-lab/og-image.svg' }],
178190

179191
// Twitter Card
180192
['meta', { name: 'twitter:card', content: 'summary_large_image' }],
181-
['meta', { name: 'twitter:title', content: 'SQL Lab · 80 个能跑的 MySQL 优化实战案例' }],
193+
['meta', { name: 'twitter:title', content: 'SQL Lab · 86 个能跑的 MySQL/TiDB 优化实战案例' }],
182194
['meta', { name: 'twitter:description', content: '一套能跑、能量化对比的 MySQL 优化实战案例集。Docker 一键复现,bad/good EXPLAIN 量化对比。' }],
183195
['meta', { name: 'twitter:image', content: 'https://slowleelab.github.io/sql-lab/og-image.svg' }],
184196
],

docs/.vitepress/theme/components/HomeFeatures.vue

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
import { withBase } from 'vitepress'
77
88
const stats = [
9-
{ number: '80', label: '精选案例' },
10-
{ number: '7', label: '场景分类' },
11-
{ number: '2', label: 'MySQL 版本' },
9+
{ number: '86', label: '精选案例' },
10+
{ number: '8', label: '场景分类' },
11+
{ number: '3', label: '数据库引擎' },
1212
{ number: '100%', label: '可复现' },
1313
]
1414
@@ -20,6 +20,7 @@ const categories = [
2020
{ icon: '🏗️', name: '架构级优化', count: '11 个案例', link: withBase('/cases/architecture/52-dynamic-filter') },
2121
{ icon: '🔒', name: '事务与锁', count: '9 个案例', link: withBase('/cases/transaction/63-deadlock-analysis') },
2222
{ icon: '', name: '优化器与 8.0', count: '9 个案例', link: withBase('/cases/optimizer/72-descending-index') },
23+
{ icon: '🔮', name: 'TiDB 分布式优化', count: '6 个案例', link: withBase('/cases/tidb/81-tidb-explain-tree') },
2324
{ icon: '🚀', name: '全部案例', count: '查看总览', link: withBase('/cases/') },
2425
]
2526
</script>
@@ -35,8 +36,8 @@ const categories = [
3536

3637
<!-- 分类导航 -->
3738
<div class="home-categories">
38-
<h2 class="home-categories-title">七大场景 · 80 个案例</h2>
39-
<p class="home-categories-subtitle">从索引失效到事务锁、从查询改写到 8.0 新特性,覆盖 MySQL 优化全链路</p>
39+
<h2 class="home-categories-title">八大场景 · 86 个案例</h2>
40+
<p class="home-categories-subtitle">从索引失效到事务锁、从查询改写到 8.0 新特性,覆盖 MySQL + TiDB 优化全链路</p>
4041
<div class="home-category-grid">
4142
<a
4243
v-for="c in categories"

docs/404.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
## 快速导航
66

7-
- [🏠 返回首页](/) — 查看 80 个精选案例
7+
- [🏠 返回首页](/) — 查看 86 个精选案例
88
- [📚 案例总览](/cases/) — 按分类浏览所有案例
99
- [📖 快速开始](/guide/quick-start) — Docker 一键跑通第一个案例
1010
- [❓ 如何阅读案例](/guide/how-to-read) — 理解 EXPLAIN 和案例结构

docs/cases/index.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# 案例总览
22

3-
**80 个精选案例**,覆盖 MySQL 优化的七大核心场景。每个案例都带真实数据,可一键复现。
3+
**86 个精选案例**,覆盖 MySQL + TiDB 优化的八大核心场景。每个案例都带真实数据,可一键复现。
44

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

@@ -116,6 +116,17 @@
116116
| 78 | [派生条件下推优化](./optimizer/78-derived-condition-pushdown) | ⭐⭐⭐ | 5.7 & 8.0 |
117117
| 79 | [大批量 UPDATE 分批优化](./optimizer/79-batch-update) | ⭐⭐ | 5.7 & 8.0 |
118118
| 80 | [慢查询排查方法论](./optimizer/80-slow-query-diagnosis) | ⭐⭐⭐ | 5.7 & 8.0 |
119+
## 八、TiDB 分布式优化(6 个)
120+
121+
| # | 案例 | 难度 | 版本 |
122+
|---|------|:----:|:----:|
123+
| 81 | [TiDB EXPLAIN 算子树解读](./tidb/81-tidb-explain-tree) | ⭐⭐ | TiDB |
124+
| 82 | [协处理器下推优化](./tidb/82-coprocessor-pushdown) | ⭐⭐⭐ | TiDB |
125+
| 83 | [AUTO_RANDOM 避免写热点](./tidb/83-auto-random) | ⭐⭐ | TiDB |
126+
| 84 | [TiDB 统计信息管理](./tidb/84-tidb-statistics) | ⭐⭐⭐ | TiDB |
127+
| 85 | [TiDB 事务模型对比](./tidb/85-tidb-transaction) | ⭐⭐⭐ | TiDB |
128+
| 86 | [IndexLookUp 回表与覆盖索引](./tidb/86-index-lookup) | ⭐⭐ | TiDB |
129+
119130
---
120131

121132
::: tip 难度说明

0 commit comments

Comments
 (0)