目录
引言:性能瓶颈的典型场景
在某电商平台的双11备战期间,核心订单库的MySQL实例突然出现严重性能问题。监控数据显示,订单查询接口响应时间从200ms飙升至12秒,TPS(每秒事务数)从3000骤降至400。DBA团队通过
SHOW PROCESSLIST
发现大量SELECT * FROM orders WHERE order_date BETWEEN '2024-01-01' AND '2024-12-31'
类型的查询堆积,这成为本次优化的关键切入点。
第一章 索引优化:B+树结构的深度博弈
1.1 索引失效的典型表现
通过EXPLAIN
分析发现,原查询未命中任何索引:
EXPLAIN SELECT order_id, user_id, amount
FROM orders
WHERE order_date BETWEEN '2024-01-01' AND '2024-12-31'
AND status = 'PAID';
输出结果中type=ALL
,rows=2.1e7
,说明进行了全表扫描。根本原因在于:
order_date
字段未建立索引- 复合索引缺失导致索引覆盖失效
1.2 索引重构策略
1.2.1 单列索引优化
-- 创建基础索引
CREATE INDEX idx_order_date ON orders(order_date);
-- 验证索引效果
EXPLAIN SELECT ...
-- 输出显示type=range, key=idx_order_date
1.2.2 复合索引设计
根据查询特征创建覆盖索引:
CREATE INDEX idx_order_date_status ON orders(order_date, status);
执行计划对比:
优化前 | 优化后 |
---|---|
type=ALL | type=ref |
rows=2.1e7 | rows=12.3k |
Extra: Using filesort | Extra: Using index |
1.3 索引维护最佳实践
-- 定期分析表统计信息
ANALYZE TABLE orders;
-- 监控索引碎片
SELECT
index_name,
index_type,
non_unique,
index_length,
avg_fragmentation_in_percent
FROM information_schema.statistics
WHERE table_schema = 'ecommerce' AND table_name = 'orders';
第二章 查询重写:从N+1到批处理
2.1 原始查询的问题分析
业务代码中存在典型N+1查询:
# Python伪代码示例
orders = Order.objects.filter(date_range) # 触发1次SQL
for order in orders:
payme