随着项目数据量的增长,接口响应慢、查询卡顿、数据库压力飙升成为常见问题。本文将结合实际项目,从多个角度(数据库设计、查询优化、缓存策略、搜索引擎、分库分表)出发,详解如何优化查询性能。
✅ 优化目标
- 降低查询响应时间
- 减轻数据库压力
- 提升系统稳定性和可扩展性
🧱 一、MySQL 查询层优化
1. 添加合适索引
- 针对
WHERE、ORDER BY、JOIN字段建立联合索引 - 避免在索引字段使用函数或不等号(如
!=,<>)
示例:
-- 不推荐:函数使索引失效
SELECT * FROM users WHERE DATE(created_at) = '2024-01-01';
-- 推荐写法:
SELECT * FROM users WHERE created_at >= '2024-01-01' AND created_at < '2024-01-02';
2. 分页优化
-- 慢分页
SELECT * FROM orders ORDER BY id LIMIT 100000, 10;
-- 快分页
SELECT * FROM orders WHERE id > 100000 ORDER BY id LIMIT 10;
3. SQL 查询重写
- 避免
SELECT * - 拆解复杂 JOIN 查询为多次小查询 + 内存拼接
🚀 二、引入缓存层
使用场景
- 高频访问、数据变动不频繁
- 详情页、列表页、配置信息等
常见缓存方案
| 缓存类型 | 场景 | 推荐工具 |
|---|---|---|
| 本地缓存 | 单机、热点数据 | Caffeine、Guava |
| 分布式缓存 | 多节点共享 | Redis、Memcached |
示例架构:
public User getUserDetail(Long id) {
User user = redis.get("user:" + id);
if (user != null) return user;
user = db.queryById(id);
redis.set("user:" + id, user, 10min);
return user;
}
🔎 三、复杂查询交给 Elasticsearch
示例场景
- 商品搜索
- 博客模糊匹配
- 用户行为分析
示例对比:
-- MySQL 查询:
SELECT * FROM article WHERE title LIKE '%mysql%' AND tag='数据库';
-- ES DSL 查询:
{
"query": {
"bool": {
"must": [
{ "match": { "title": "mysql" } },
{ "term": { "tag": "数据库" } }
]
}
}
}
🏗️ 四、分库分表应对大数据量
常见方案:
| 类型 | 特点 | 工具 |
|---|---|---|
| 水平分表 | 按业务主键分片 | ShardingSphere, MyCat |
| 垂直拆库 | 按模块拆表至多个库 | 手动拆库、微服务 |
示例:使用 Sharding-JDBC 分片
tables:
user:
actualDataNodes: ds${0..1}.user_${0..15}
tableStrategy:
inline:
shardingColumn: user_id
algorithmExpression: user_${user_id % 16}
🧠 五、异步化处理非核心查询
- 使用消息队列投递
- 后台批处理更新缓存
- 用队列防抖聚合更新
✅ 最佳实践组合推荐
| 场景 | 推荐优化组合 |
|---|---|
| 用户详情页 | Redis 缓存 + ID 索引优化 |
| 搜索接口 | Elasticsearch + 缓存 |
| 大列表分页 | 游标分页 + 分表 |
| 报表查询 | MySQL 预计算 + 缓存 + 异步更新 |
| 订单系统 | 分库分表 + 缓存热点订单 |
📌 总结
接口慢不是“数据库背锅”,而是系统全链路的问题。
需要数据库优化 + 缓存加速 + 搜索引擎 + 分布式架构的组合拳。
查询慢 ≠ SQL 慢,更多时候是整体架构设计不合理。