什么时候开始做性能优化?评判需要优化的指标是什么?
## 一、优化判断的三个层次
**A. 代码层面(静态分析)**
判断标准:
**1. N+1 查询问题:循环中调用数据库查询**
- 每篇文章都查询分类和用户 → N+1 查询
- 量化指标:查询次数 = 1(主查询)+ N×2(分类+用户)
**2. 重复代码:相同的 try-catch 块**
- 量化指标:重复代码行数 > 3 行 → 需要提取
**3. 低效循环:索引循环 vs 增强for循环**
- 量化指标:循环内调用 get(i) → 低效
**B. 性能层面(动态指标)**
关键指标及阈值:
```
指标 阈值 测量方法 优化优先级
响应时间 > 500ms System.currentTimeMillis() 高
数据库查询时间 > 100ms MyBatis 日志或慢查询日志 高
查询次数 > 5 次/请求 统计 Mapper 调用次数 中
内存使用 > 80% 堆内存 JVM 监控 中
GC 频率 > 10 次/分钟 GC 日志 低
并发吞吐量 < 100 QPS 压测工具 低
```
量化方法:
```
// 在 Controller 或 Service 方法中添加计时
long startTime = System.currentTimeMillis();
try {
// 业务逻辑
Article article = articleService.getArticleByStatusAndId(status, id);
// ...
} finally {
long duration = System.currentTimeMillis() - startTime;
if (duration > 500) {
log.warn("慢查询: getArticleDetailPage 耗时 {}ms, articleId={}", duration, articleId);
}
}
```
**C. 用户体验层面(业务指标)**
判断标准:
- 页面加载时间 > 3 秒 → 用户流失率上升 32%
- 首字节时间(TTFB) > 1 秒 → 感知卡顿
- 并发用户数 > 100 时响应时间激增 → 需要优化
## 二、实用的量化工具
**1. MyBatis 慢查询日志**
```
# application.properties
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
logging.level.com.kernelcode.blog.mapper=DEBUG
```
**2. Spring AOP 性能监控**
```java
@Aspect
@Component
public class PerformanceMonitorAspect {
@Around("execution(* com.kernelcode.blog.service.*.*(..))")
public Object monitorPerformance(ProceedingJoinPoint joinPoint) throws Throwable {
long startTime = System.currentTimeMillis();
Object result = joinPoint.proceed();
long duration = System.currentTimeMillis() - startTime;
if (duration > 100) {
log.warn("慢方法: {}.{} 耗时 {}ms",
joinPoint.getTarget().getClass().getSimpleName(),
joinPoint.getSignature().getName(),
duration);
}
return result;
}
}
```
**3. 数据库慢查询日志**
```
-- MySQL 配置
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 0.1; -- 100ms
SET GLOBAL slow_query_log_file = '/var/log/mysql/slow-query.log';
```
## 三、优化决策树
```
是否需要优化?
├─ 代码层面
│ ├─ 有 N+1 查询? → 是 → 优化
│ ├─ 有重复代码? → 是 → 重构
│ └─ 有低效算法? → 是 → 优化
├─ 性能层面
│ ├─ 响应时间 > 500ms? → 是 → 优化
│ ├─ 查询时间 > 100ms? → 是 → 优化
│ └─ 查询次数 > 5? → 是 → 优化
└─ 用户体验
├─ 页面加载 > 3s? → 是 → 优化
└─ 并发性能差? → 是 → 优化
```
## 四、总结(本项目)
立即优化(高优先级):
- pageArticle() 的 N+1 查询 → 批量查询
- listRandomArticle() 的 ORDER BY RAND() → 缓存或预生成
- 文章详情页的 8+ 次查询 → 合并查询或缓存
计划优化(中优先级):
- 添加性能监控 AOP
- 配置慢查询日志
- 热门文章缓存
观察优化(低优先级):
- JVM GC 调优
- 数据库连接池优化
- 静态资源 CDN
**核心原则:不要过早优化,但要有数据支撑。先用工具量化问题,再决定是否优化。**