目录
数据库性能优化的完整指南
作者:文文
数据库性能优化的三个层次
第一层:SQL 优化 → 最直接,效果最明显
第二层:索引设计 → 需要经验和分析
第三层:架构设计 → 长期解决方案
第一层:SQL 优化
分析查询计划
-- MySQL
EXPLAIN SELECT * FROM users WHERE email = 'alice@example.com';
-- 关键指标
-- type: ALL (全表扫描) < INDEX < CONST (最优)
-- rows: 扫描行数,越少越好
-- Extra: Using index (很好) vs Using where (差)
常见优化技巧
- **避免 SELECT ***
-- 不好
SELECT * FROM users;
-- 好
SELECT id, name, email FROM users;
- 使用 JOIN 替代子查询
-- 慢
SELECT * FROM users WHERE id IN (SELECT user_id FROM orders);
-- 快
SELECT DISTINCT u.* FROM users u
INNER JOIN orders o ON u.id = o.user_id;
- 避免函数导致索引失效
-- 不好
SELECT * FROM users WHERE YEAR(created_at) = 2024;
-- 好
SELECT * FROM users WHERE created_at >= '2024-01-01' AND created_at < '2025-01-01';
第二层:索引设计
索引类型对比
| 类型 | 用途 | 优点 | 缺点 |
|---|---|---|---|
| 主键索引 | 唯一标识 | 快速查找 | 只有一个 |
| 唯一索引 | 保证唯一性 | 快速查找 | 修改成本高 |
| 普通索引 | 加速查询 | 灵活 | 需要维护 |
| 复合索引 | 多条件查询 | 覆盖查询 | 顺序重要 |
| 全文索引 | 文本搜索 | 支持模糊搜索 | 占用空间大 |
复合索引的最优顺序
-- 假设有三个查询条件:status, created_at, user_id
-- 创建复合索引的顺序:
CREATE INDEX idx_composite ON orders(status, created_at, user_id);
-- 遵循原则:
-- 1. 等值条件优先(status)
-- 2. 排序条件次之(created_at)
-- 3. 范围条件最后(user_id)
第三层:缓存策略
Redis 缓存模式
# 旁路缓存 (Cache-Aside)
def get_user(user_id):
# 尝试从缓存读取
user = redis.get(f'user:{user_id}')
if user:
return user
# 缓存未命中,查询数据库
user = db.query(f'SELECT * FROM users WHERE id={user_id}')
# 写入缓存
redis.set(f'user:{user_id}', user, ex=3600)
return user
缓存击穿解决方案
# 布隆过滤器 (Bloom Filter)
from pybloom import BloomFilter
bloom = BloomFilter(capacity=100000, error_rate=0.001)
def get_user_safe(user_id):
# 检查 ID 是否存在
if user_id not in bloom:
return None # ID 不存在,直接返回
# 查询缓存和数据库
return get_user(user_id)
第四层:分布式架构
分库分表
原始表:users (1000万行)
↓
分库:db0, db1, db2, db3 (4 个库)
分表:users_0, users_1, users_2, users_3 (每库 4 个表)
路由规则:shard_id = user_id % 16
读写分离
主库(写) ← 应用写操作
↓
从库(读) ← 应用读操作
优点:
- 提高读取吞吐量
- 减轻主库压力
缺点:
- 主从延迟
- 数据不一致风险
监控和诊断
关键指标
- 查询延迟:平均响应时间、P95、P99
- 吞吐量:每秒处理的查询数
- 连接数:活跃连接、最大连接
- 资源使用:CPU、内存、磁盘 I/O
慢查询日志
-- MySQL
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 1;
-- 查看慢查询
SHOW GLOBAL STATUS LIKE 'Slow%';
文文,2026 年 3 月 16 日
