数据库慢查询优化:我是怎么把接口从 3 秒干到 80ms 的

admin 发布于 12 小时前 5 次阅读


数据库性能问题是后端开发中最常见的瓶颈之一。一个优化良好的数据库不仅能提升用户体验,还能显著降低服务器成本。本文将分享 7 个经过实战验证的数据库优化方案,帮助你将查询速度提升 10 倍以上。

**索引优化:让查询飞起来**

索引是数据库优化的第一步。合理的索引设计能将查询时间从秒级降到毫秒级。

```sql
-- 为常用查询字段创建索引
CREATE INDEX idx_user_email ON users(email);
CREATE INDEX idx_order_status_date ON orders(status, created_at);

-- 使用复合索引优化多条件查询
CREATE INDEX idx_product_category_price ON products(category_id, price DESC);
```

注意避免过度索引。每个索引都会占用存储空间并降低写入性能。只为高频查询字段和 WHERE、JOIN、ORDER BY 中的列创建索引。

**查询优化:避免全表扫描**

使用 EXPLAIN 分析查询执行计划,识别性能瓶颈:

```sql
EXPLAIN SELECT * FROM orders
WHERE user_id = 1001
AND status = 'pending';
```

优化技巧包括:
- 避免 SELECT *,只查询需要的字段
- 使用 LIMIT 限制返回结果
- 将子查询改写为 JOIN
- 避免在 WHERE 子句中对索引字段使用函数

```sql
-- 不好的写法
SELECT * FROM users WHERE YEAR(created_at) = 2024;

-- 优化后
SELECT id, name, email FROM users
WHERE created_at >= '2024-01-01' AND created_at < '2025-01-01'; ``` **连接池配置:提升并发能力** 数据库连接的创建和销毁开销很大。使用连接池可以复用连接,显著提升并发性能。 ```javascript // Node.js 示例 const mysql = require('mysql2'); const pool = mysql.createPool({ host: 'localhost', user: 'root', database: 'mydb', waitForConnections: true, connectionLimit: 10, queueLimit: 0, idleTimeout: 60000 }); ``` 根据应用负载调整连接池大小。一般建议设置为 CPU 核心数的 2-4 倍。 **分页优化:深度分页的解决方案** 传统的 OFFSET 分页在数据量大时性能急剧下降: ```sql -- 性能差:需要扫描前 100000 条记录 SELECT * FROM posts ORDER BY id LIMIT 100000, 20; -- 优化:使用游标分页 SELECT * FROM posts WHERE id > 100000
ORDER BY id LIMIT 20;
```

对于需要跳页的场景,可以缓存页码与 ID 的映射关系。

**缓存策略:减少数据库压力**

将热点数据缓存到 Redis 中,可以减少 80% 以上的数据库查询:

```python
import redis
import json

r = redis.Redis(host='localhost', port=6379)

def get_user(user_id):
# 先查缓存
cache_key = f'user:{user_id}'
cached = r.get(cache_key)
if cached:
return json.loads(cached)

# 缓存未命中,查数据库
user = db.query('SELECT * FROM users WHERE id = %s', user_id)
r.setex(cache_key, 3600, json.dumps(user))
return user
```

**批量操作:减少网络往返**

将多次单条操作合并为批量操作:

```sql
-- 不好的做法:循环插入
INSERT INTO logs (user_id, action) VALUES (1, 'login');
INSERT INTO logs (user_id, action) VALUES (2, 'logout');

-- 优化:批量插入
INSERT INTO logs (user_id, action) VALUES
(1, 'login'), (2, 'logout'), (3, 'view');
```

批量操作能将性能提升 10-100 倍,特别适合数据导入和批处理场景。

**数据归档:保持表体积可控**

随着业务增长,历史数据会拖慢查询速度。定期将冷数据归档到历史表:

```sql
-- 创建归档表
CREATE TABLE orders_archive LIKE orders;

-- 归档 6 个月前的订单
INSERT INTO orders_archive
SELECT * FROM orders
WHERE created_at < DATE_SUB(NOW(), INTERVAL 6 MONTH); DELETE FROM orders WHERE created_at < DATE_SUB(NOW(), INTERVAL 6 MONTH); ``` **总结** 数据库优化是一个持续的过程。从索引设计、查询优化到缓存策略,每个环节都可能成为性能瓶颈。建议定期使用慢查询日志和监控工具分析数据库性能,针对性地进行优化。记住,过早优化是万恶之源,先用数据说话,再动手优化。

此作者没有提供个人介绍。
最后更新于 2026-03-11