学习目标
- 掌握Java性能优化的核心技巧
- 学习JVM调优和内存管理
- 掌握性能监控工具的使用
- 了解Spring Boot性能优化最佳实践
- 学习数据库性能优化技巧
一、Java性能优化基础
1. 代码层面优化
java
复制代码
// 1. 字符串优化
public class StringOptimization {
// ❌ 低效:频繁字符串拼接
public String inefficientConcat(String[] words) {
String result = "";
for (String word : words) {
result += word + " "; // 每次都创建新String对象
}
return result;
}
// ✅ 高效:使用StringBuilder
public String efficientConcat(String[] words) {
StringBuilder sb = new StringBuilder();
for (String word : words) {
sb.append(word).append(" ");
}
return sb.toString();
}
// ✅ 更高效:预分配容量
public String optimizedConcat(String[] words) {
StringBuilder sb = new StringBuilder(words.length * 10); // 预分配容量
for (String word : words) {
sb.append(word).append(" ");
}
return sb.toString();
}
}
// 2. 集合优化
public class CollectionOptimization {
// ❌ 低效:频繁扩容
public List<String> inefficientList() {
List<String> list = new ArrayList<>(); // 默认容量10
for (int i = 0; i < 1000; i++) {
list.add("item" + i); // 可能触发多次扩容
}
return list;
}
// ✅ 高效:预分配容量
public List<String> efficientList() {
List<String> list = new ArrayList<>(1000); // 预分配容量
for (int i = 0; i < 1000; i++) {
list.add("item" + i);
}
return list;
}
// 3. 选择合适的集合类型
public void chooseRightCollection() {
// 频繁随机访问 - 使用ArrayList
List<String> randomAccess = new ArrayList<>();
// 频繁插入删除 - 使用LinkedList
List<String> frequentModification = new LinkedList<>();
// 去重 - 使用HashSet
Set<String> uniqueItems = new HashSet<>();
// 有序去重 - 使用TreeSet
Set<String> sortedUnique = new TreeSet<>();
// 键值对 - 使用HashMap
Map<String, String> keyValue = new HashMap<>();
}
}
// 3. 循环优化
public class LoopOptimization {
// ❌ 低效:在循环中调用方法
public int inefficientLoop(List<String> list) {
int sum = 0;
for (int i = 0; i < list.size(); i++) { // 每次循环都调用size()
sum += list.get(i).length();
}
return sum;
}
// ✅ 高效:缓存方法调用结果
public int efficientLoop(List<String> list) {
int sum = 0;
int size = list.size(); // 缓存size()结果
for (int i = 0; i < size; i++) {
sum += list.get(i).length();
}
return sum;
}
// ✅ 更高效:使用增强for循环
public int enhancedForLoop(List<String> list) {
int sum = 0;
for (String item : list) {
sum += item.length();
}
return sum;
}
}
2. 对象创建优化
java
复制代码
// 对象池模式
public class ObjectPool<T> {
private final Queue<T> pool;
private final Supplier<T> factory;
private final int maxSize;
public ObjectPool(Supplier<T> factory, int maxSize) {
this.factory = factory;
this.maxSize = maxSize;
this.pool = new ConcurrentLinkedQueue<>();
}
public T borrow() {
T object = pool.poll();
if (object == null) {
object = factory.get();
}
return object;
}
public void returnObject(T object) {
if (pool.size() < maxSize) {
pool.offer(object);
}
}
}
// 使用示例
public class StringBufferPool {
private static final ObjectPool<StringBuilder> POOL =
new ObjectPool<>(StringBuilder::new, 10);
public String processString(List<String> items) {
StringBuilder sb = POOL.borrow();
try {
for (String item : items) {
sb.append(item).append(" ");
}
return sb.toString();
} finally {
sb.setLength(0); // 清空内容
POOL.returnObject(sb);
}
}
}
二、JVM调优与内存管理
1. 内存区域优化
java
复制代码
// 内存使用监控
public class MemoryMonitor {
private static final MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean();
public void printMemoryUsage() {
MemoryUsage heapUsage = memoryBean.getHeapMemoryUsage();
MemoryUsage nonHeapUsage = memoryBean.getNonHeapMemoryUsage();
System.out.println("=== 堆内存使用情况 ===");
System.out.println("已使用: " + formatBytes(heapUsage.getUsed()));
System.out.println("已提交: " + formatBytes(heapUsage.getCommitted()));
System.out.println("最大: " + formatBytes(heapUsage.getMax()));
System.out.println("使用率: " + getUsagePercentage(heapUsage) + "%");
System.out.println("\n=== 非堆内存使用情况 ===");
System.out.println("已使用: " + formatBytes(nonHeapUsage.getUsed()));
System.out.println("已提交: " + formatBytes(nonHeapUsage.getCommitted()));
System.out.println("最大: " + formatBytes(nonHeapUsage.getMax()));
}
private String formatBytes(long bytes) {
if (bytes < 1024) return bytes + " B";
if (bytes < 1024 * 1024) return String.format("%.2f KB", bytes / 1024.0);
if (bytes < 1024 * 1024 * 1024) return String.format("%.2f MB", bytes / (1024.0 * 1024));
return String.format("%.2f GB", bytes / (1024.0 * 1024 * 1024));
}
private double getUsagePercentage(MemoryUsage usage) {
return (double) usage.getUsed() / usage.getMax() * 100;
}
}
// 垃圾回收监控
public class GCMonitor {
private static final List<GarbageCollectorMXBean> gcBeans =
ManagementFactory.getGarbageCollectorMXBeans();
public void printGCInfo() {
System.out.println("=== 垃圾回收器信息 ===");
for (GarbageCollectorMXBean gcBean : gcBeans) {
System.out.println("名称: " + gcBean.getName());
System.out.println("收集次数: " + gcBean.getCollectionCount());
System.out.println("收集时间: " + gcBean.getCollectionTime() + " ms");
System.out.println("内存池: " + Arrays.toString(gcBean.getMemoryPoolNames()));
System.out.println("---");
}
}
}
2. JVM参数调优
java
复制代码
// JVM参数配置示例
public class JVMConfigExample {
/*
* 推荐的JVM参数配置:
*
* 1. 堆内存设置
* -Xms2g -Xmx2g # 初始堆大小和最大堆大小
* -XX:NewRatio=2 # 新生代与老年代比例 1:2
* -XX:SurvivorRatio=8 # Eden与Survivor比例 8:1:1
*
* 2. 垃圾回收器选择
* -XX:+UseG1GC # 使用G1垃圾回收器
* -XX:MaxGCPauseMillis=200 # 最大GC暂停时间
* -XX:G1HeapRegionSize=16m # G1区域大小
*
* 3. GC日志
* -XX:+PrintGC # 打印GC信息
* -XX:+PrintGCDetails # 打印GC详细信息
* -XX:+PrintGCTimeStamps # 打印GC时间戳
* -Xloggc:gc.log # GC日志文件
*
* 4. 其他优化
* -XX:+UseStringDeduplication # 字符串去重
* -XX:+OptimizeStringConcat # 优化字符串拼接
* -XX:+UseCompressedOops # 压缩指针
*/
}
三、Spring Boot性能优化
1. 应用配置优化
java
复制代码
// 1. 数据库连接池优化
@Configuration
public class DatabaseConfig {
@Bean
@ConfigurationProperties("spring.datasource.hikari")
public HikariConfig hikariConfig() {
HikariConfig config = new HikariConfig();
// 连接池大小
config.setMaximumPoolSize(20);
config.setMinimumIdle(5);
// 连接超时
config.setConnectionTimeout(30000);
config.setIdleTimeout(600000);
// 连接生命周期
config.setMaxLifetime(1800000);
// 连接测试
config.setConnectionTestQuery("SELECT 1");
config.setValidationTimeout(5000);
return config;
}
@Bean
public DataSource dataSource() {
return new HikariDataSource(hikariConfig());
}
}
// 2. 缓存配置优化
@Configuration
@EnableCaching
public class CacheConfig {
@Bean
public CacheManager cacheManager(RedisConnectionFactory connectionFactory) {
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofMinutes(30)) // 默认过期时间
.serializeKeysWith(RedisSerializationContext.SerializationPair
.fromSerializer(new StringRedisSerializer()))
.serializeValuesWith(RedisSerializationContext.SerializationPair
.fromSerializer(new GenericJackson2JsonRedisSerializer()));
return RedisCacheManager.builder(connectionFactory)
.cacheDefaults(config)
.withCacheConfiguration("users", config.entryTtl(Duration.ofHours(1)))
.withCacheConfiguration("products", config.entryTtl(Duration.ofMinutes(10)))
.build();
}
}
// 3. 异步配置优化
@Configuration
@EnableAsync
public class AsyncConfig {
@Bean("taskExecutor")
public ThreadPoolTaskExecutor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(20);
executor.setQueueCapacity(200);
executor.setKeepAliveSeconds(60);
executor.setThreadNamePrefix("async-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
}
2. 业务层优化
java
复制代码
// 1. 批量操作优化
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
// ❌ 低效:逐个插入
public void inefficientBatchInsert(List<User> users) {
for (User user : users) {
userMapper.insert(user);
}
}
// ✅ 高效:批量插入
public void efficientBatchInsert(List<User> users) {
userMapper.batchInsert(users);
}
// 2. 分页查询优化
public PageResult<User> getUsersWithPagination(int page, int size) {
// 使用MyBatis Plus分页插件
Page<User> pageInfo = new Page<>(page, size);
IPage<User> result = userMapper.selectPage(pageInfo, null);
return PageResult.<User>builder()
.records(result.getRecords())
.total(result.getTotal())
.current(result.getCurrent())
.size(result.getSize())
.pages(result.getPages())
.build();
}
}
// 2. 缓存策略优化
@Service
public class ProductService {
@Autowired
private ProductMapper productMapper;
@Cacheable(value = "products", key = "#id", unless = "#result == null")
public Product getProductById(Long id) {
return productMapper.selectById(id);
}
@CacheEvict(value = "products", key = "#product.id")
public void updateProduct(Product product) {
productMapper.updateById(product);
}
@CacheEvict(value = "products", allEntries = true)
public void clearAllCache() {
// 清空所有产品缓存
}
}
// 3. 数据库查询优化
@Repository
public class OrderMapper extends BaseMapper<Order> {
// 使用索引优化查询
@Select("SELECT * FROM orders WHERE user_id = #{userId} AND status = #{status} " +
"ORDER BY create_time DESC LIMIT #{offset}, #{limit}")
List<Order> findOrdersByUserAndStatus(@Param("userId") Long userId,
@Param("status") String status,
@Param("offset") int offset,
@Param("limit") int limit);
// 避免N+1查询问题
@Select("SELECT o.*, u.username, u.email FROM orders o " +
"LEFT JOIN users u ON o.user_id = u.id " +
"WHERE o.id IN " +
"<foreach collection='orderIds' item='id' open='(' separator=',' close=')'>" +
"#{id}" +
"</foreach>")
List<OrderWithUser> findOrdersWithUsers(@Param("orderIds") List<Long> orderIds);
}
四、性能监控工具
1. 应用性能监控
java
复制代码
// 1. 自定义性能监控
@Component
public class PerformanceMonitor {
private final MeterRegistry meterRegistry;
private final Timer.Sample sample;
public PerformanceMonitor(MeterRegistry meterRegistry) {
this.meterRegistry = meterRegistry;
this.sample = Timer.start(meterRegistry);
}
@EventListener
public void handleRequest(RequestEvent event) {
Timer.Sample requestSample = Timer.start(meterRegistry);
try {
// 处理请求
processRequest(event);
} finally {
requestSample.stop(Timer.builder("http.request.duration")
.tag("method", event.getMethod())
.tag("uri", event.getUri())
.register(meterRegistry));
}
}
private void processRequest(RequestEvent event) {
// 业务逻辑
}
}
// 2. 业务指标监控
@Service
public class BusinessMetricsService {
private final Counter orderCounter;
private final Timer orderProcessingTimer;
private final Gauge activeUsersGauge;
public BusinessMetricsService(MeterRegistry meterRegistry) {
this.orderCounter = Counter.builder("orders.created")
.description("Number of orders created")
.register(meterRegistry);
this.orderProcessingTimer = Timer.builder("orders.processing.time")
.description("Order processing time")
.register(meterRegistry);
this.activeUsersGauge = Gauge.builder("users.active")
.description("Number of active users")
.register(meterRegistry, this, BusinessMetricsService::getActiveUserCount);
}
public void recordOrderCreated() {
orderCounter.increment();
}
public void recordOrderProcessingTime(Duration duration) {
orderProcessingTimer.record(duration);
}
private double getActiveUserCount() {
// 返回当前活跃用户数
return 100.0; // 示例值
}
}
// 3. 健康检查增强
@Component
public class CustomHealthIndicator implements HealthIndicator {
@Autowired
private DataSource dataSource;
@Override
public Health health() {
try {
// 检查数据库连接
try (Connection connection = dataSource.getConnection()) {
if (connection.isValid(5)) {
return Health.up()
.withDetail("database", "Available")
.withDetail("responseTime", "5ms")
.build();
}
}
} catch (Exception e) {
return Health.down()
.withDetail("database", "Unavailable")
.withDetail("error", e.getMessage())
.build();
}
return Health.down()
.withDetail("database", "Unknown status")
.build();
}
}
2. 日志监控
java
复制代码
// 1. 结构化日志
@Slf4j
@Service
public class OrderService {
public Order createOrder(OrderRequest request) {
MDC.put("userId", String.valueOf(request.getUserId()));
MDC.put("orderId", UUID.randomUUID().toString());
try {
log.info("Creating order for user: {}", request.getUserId());
Order order = new Order();
order.setUserId(request.getUserId());
order.setAmount(request.getAmount());
order.setStatus("PENDING");
// 业务逻辑
processOrder(order);
log.info("Order created successfully: {}", order.getId());
return order;
} catch (Exception e) {
log.error("Failed to create order for user: {}", request.getUserId(), e);
throw e;
} finally {
MDC.clear();
}
}
private void processOrder(Order order) {
// 订单处理逻辑
}
}
// 2. 性能日志
@Aspect
@Component
public class PerformanceLoggingAspect {
private static final Logger logger = LoggerFactory.getLogger(PerformanceLoggingAspect.class);
@Around("@annotation(PerformanceLog)")
public Object logPerformance(ProceedingJoinPoint joinPoint) throws Throwable {
long startTime = System.currentTimeMillis();
String methodName = joinPoint.getSignature().getName();
try {
Object result = joinPoint.proceed();
long executionTime = System.currentTimeMillis() - startTime;
logger.info("Method {} executed in {} ms", methodName, executionTime);
return result;
} catch (Exception e) {
long executionTime = System.currentTimeMillis() - startTime;
logger.error("Method {} failed after {} ms", methodName, executionTime, e);
throw e;
}
}
}
// 使用注解
@PerformanceLog
@Service
public class UserService {
public User getUserById(Long id) {
// 业务逻辑
return new User();
}
}
五、数据库性能优化
1. 查询优化
java
复制代码
// 1. 索引优化
@Repository
public class OptimizedUserRepository {
// 使用复合索引优化查询
@Select("SELECT * FROM users WHERE status = #{status} AND created_at >= #{startDate} " +
"ORDER BY created_at DESC LIMIT #{limit}")
List<User> findActiveUsersAfterDate(@Param("status") String status,
@Param("startDate") LocalDateTime startDate,
@Param("limit") int limit);
// 避免SELECT *,只查询需要的字段
@Select("SELECT id, username, email, created_at FROM users WHERE id = #{id}")
User findUserBasicInfo(@Param("id") Long id);
// 使用EXISTS替代IN
@Select("SELECT u.* FROM users u WHERE EXISTS " +
"(SELECT 1 FROM orders o WHERE o.user_id = u.id AND o.status = #{status})")
List<User> findUsersWithOrders(@Param("status") String status);
}
// 2. 分页优化
@Service
public class PaginationService {
@Autowired
private UserMapper userMapper;
// 使用游标分页替代OFFSET分页
public PageResult<User> getUsersWithCursor(Long lastId, int limit) {
List<User> users = userMapper.findUsersAfterId(lastId, limit);
Long nextCursor = users.isEmpty() ? null : users.get(users.size() - 1).getId();
boolean hasNext = users.size() == limit;
return PageResult.<User>builder()
.records(users)
.nextCursor(nextCursor)
.hasNext(hasNext)
.build();
}
}
// 3. 批量操作优化
@Repository
public class BatchOperationRepository {
@Autowired
private JdbcTemplate jdbcTemplate;
// 批量插入
public void batchInsert(List<User> users) {
String sql = "INSERT INTO users (username, email, created_at) VALUES (?, ?, ?)";
List<Object[]> batchArgs = users.stream()
.map(user -> new Object[]{user.getUsername(), user.getEmail(), user.getCreatedAt()})
.collect(Collectors.toList());
jdbcTemplate.batchUpdate(sql, batchArgs);
}
// 批量更新
public void batchUpdate(List<User> users) {
String sql = "UPDATE users SET username = ?, email = ? WHERE id = ?";
List<Object[]> batchArgs = users.stream()
.map(user -> new Object[]{user.getUsername(), user.getEmail(), user.getId()})
.collect(Collectors.toList());
jdbcTemplate.batchUpdate(sql, batchArgs);
}
}
2. 连接池优化
java
复制代码
// 1. HikariCP配置
@Configuration
public class HikariCPConfig {
@Bean
@ConfigurationProperties("spring.datasource.hikari")
public HikariConfig hikariConfig() {
HikariConfig config = new HikariConfig();
// 连接池大小
config.setMaximumPoolSize(20);
config.setMinimumIdle(5);
// 连接超时
config.setConnectionTimeout(30000);
config.setIdleTimeout(600000);
config.setMaxLifetime(1800000);
// 连接测试
config.setConnectionTestQuery("SELECT 1");
config.setValidationTimeout(5000);
// 性能优化
config.setLeakDetectionThreshold(60000);
config.setPoolName("HikariCP");
return config;
}
}
// 2. 连接池监控
@Component
public class ConnectionPoolMonitor {
@Autowired
private DataSource dataSource;
@Scheduled(fixedRate = 30000) // 每30秒监控一次
public void monitorConnectionPool() {
if (dataSource instanceof HikariDataSource) {
HikariDataSource hikariDataSource = (HikariDataSource) dataSource;
HikariPoolMXBean poolBean = hikariDataSource.getHikariPoolMXBean();
log.info("=== 连接池状态 ===");
log.info("活跃连接数: {}", poolBean.getActiveConnections());
log.info("空闲连接数: {}", poolBean.getIdleConnections());
log.info("总连接数: {}", poolBean.getTotalConnections());
log.info("等待连接的线程数: {}", poolBean.getThreadsAwaitingConnection());
}
}
}
六、综合实战练习
1. 性能测试工具
java
复制代码
// 1. 简单的性能测试框架
public class PerformanceTestFramework {
public static void runPerformanceTest(String testName, Runnable test, int iterations) {
System.out.println("=== 性能测试: " + testName + " ===");
// 预热
for (int i = 0; i < 10; i++) {
test.run();
}
// 正式测试
long startTime = System.nanoTime();
for (int i = 0; i < iterations; i++) {
test.run();
}
long endTime = System.nanoTime();
double avgTime = (endTime - startTime) / (double) iterations / 1_000_000; // 转换为毫秒
System.out.println("平均执行时间: " + String.format("%.2f", avgTime) + " ms");
System.out.println("总执行时间: " + (endTime - startTime) / 1_000_000 + " ms");
}
}
// 2. 字符串拼接性能测试
public class StringPerformanceTest {
public static void main(String[] args) {
String[] words = {"Hello", "World", "Java", "Performance", "Test"};
int iterations = 100000;
// 测试String拼接
PerformanceTestFramework.runPerformanceTest(
"String拼接",
() -> {
String result = "";
for (String word : words) {
result += word + " ";
}
},
iterations
);
// 测试StringBuilder
PerformanceTestFramework.runPerformanceTest(
"StringBuilder拼接",
() -> {
StringBuilder sb = new StringBuilder();
for (String word : words) {
sb.append(word).append(" ");
}
String result = sb.toString();
},
iterations
);
// 测试StringBuffer
PerformanceTestFramework.runPerformanceTest(
"StringBuffer拼接",
() -> {
StringBuffer sb = new StringBuffer();
for (String word : words) {
sb.append(word).append(" ");
}
String result = sb.toString();
},
iterations
);
}
}
2. 内存泄漏检测
java
复制代码
// 1. 内存泄漏检测工具
public class MemoryLeakDetector {
private static final List<Object> memoryLeak = new ArrayList<>();
public static void simulateMemoryLeak() {
// 模拟内存泄漏:不断添加对象但不清理
for (int i = 0; i < 1000; i++) {
memoryLeak.add(new byte[1024 * 1024]); // 每次添加1MB
}
}
public static void clearMemoryLeak() {
memoryLeak.clear();
System.gc(); // 建议垃圾回收
}
public static void printMemoryUsage() {
MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean();
MemoryUsage heapUsage = memoryBean.getHeapMemoryUsage();
System.out.println("堆内存使用: " + formatBytes(heapUsage.getUsed()));
System.out.println("堆内存最大: " + formatBytes(heapUsage.getMax()));
System.out.println("使用率: " +
String.format("%.2f", (double) heapUsage.getUsed() / heapUsage.getMax() * 100) + "%");
}
private static String formatBytes(long bytes) {
return String.format("%.2f MB", bytes / (1024.0 * 1024));
}
}
// 2. 弱引用防止内存泄漏
public class WeakReferenceExample {
private final Map<String, WeakReference<LargeObject>> cache = new HashMap<>();
public LargeObject getLargeObject(String key) {
WeakReference<LargeObject> ref = cache.get(key);
LargeObject obj = ref != null ? ref.get() : null;
if (obj == null) {
obj = new LargeObject(key);
cache.put(key, new WeakReference<>(obj));
}
return obj;
}
public void clearCache() {
cache.clear();
}
// 模拟大对象
static class LargeObject {
private final String key;
private final byte[] data;
public LargeObject(String key) {
this.key = key;
this.data = new byte[1024 * 1024]; // 1MB
}
}
}
七、性能优化最佳实践
1. 代码优化清单
java
复制代码
// 1. 性能优化检查清单
public class PerformanceChecklist {
/*
* 代码层面优化:
* ✅ 使用StringBuilder替代String拼接
* ✅ 预分配集合容量
* ✅ 选择合适的集合类型
* ✅ 避免在循环中调用方法
* ✅ 使用增强for循环
* ✅ 及时关闭资源
* ✅ 避免不必要的对象创建
* ✅ 使用对象池模式
*
* 数据库优化:
* ✅ 创建合适的索引
* ✅ 避免SELECT *
* ✅ 使用批量操作
* ✅ 优化分页查询
* ✅ 使用连接池
* ✅ 避免N+1查询
*
* 缓存优化:
* ✅ 合理设置缓存过期时间
* ✅ 使用缓存预热
* ✅ 避免缓存穿透
* ✅ 使用缓存更新策略
*
* JVM优化:
* ✅ 合理设置堆内存大小
* ✅ 选择合适的垃圾回收器
* ✅ 监控GC性能
* ✅ 使用JVM参数调优
*/
}
2. 性能监控配置
yaml
复制代码
# application.yml - 性能监控配置
management:
endpoints:
web:
exposure:
include: health,info,metrics,prometheus
endpoint:
health:
show-details: always
metrics:
export:
prometheus:
enabled: true
distribution:
percentiles-histogram:
http.server.requests: true
percentiles:
http.server.requests: 0.5, 0.95, 0.99
# 日志配置
logging:
level:
com.example: DEBUG
org.springframework.web: DEBUG
pattern:
console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level [%X{traceId},%X{spanId}] %logger{36} - %msg%n"
file: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level [%X{traceId},%X{spanId}] %logger{36} - %msg%n"
file:
name: logs/application.log
max-size: 100MB
max-history: 30
学习总结
今日重点
- 代码层面优化:字符串拼接、集合选择、循环优化
- JVM调优:内存管理、垃圾回收、参数配置
- Spring Boot优化:连接池、缓存、异步处理
- 性能监控:指标收集、日志监控、健康检查
- 数据库优化:查询优化、索引设计、批量操作
实践建议
- 使用性能测试工具验证优化效果
- 建立性能监控体系
- 定期进行性能评估
- 关注JVM和数据库性能指标
- 持续优化和调整