从零开始学习JavaWeb-16
一、MySQL 高级特性与性能优化
1. 索引深度解析与优化策略
索引类型与适用场景:
索引类型 | 数据结构 | 适用场景 | 优化效果 |
---|---|---|---|
B+树索引 | 多路平衡搜索树 | 范围查询( | 减少磁盘 I/O,提升 10-100 倍 |
哈希索引 | 哈希表 | 精确匹配( | O(1) 查询,不支持排序 |
全文索引 | 倒排索引 | 文本搜索( | 替代 |
索引失效场景:
对索引列使用函数:
WHERE YEAR(create_time) = 2025
❌隐式类型转换:
WHERE varchar_column = 123
(字符串与数字比较)❌最左前缀缺失:复合索引
(a, b)
仅查询b
列 ❌
优化方案:
-- 强制索引提示
SELECT * FROM users FORCE INDEX(idx_username) WHERE username = 'john';
-- 覆盖索引减少回表
SELECT id FROM orders WHERE status = 'PAID'; -- 只需索引列
2. 事务隔离级别与锁机制
隔离级别对比:
级别 | 脏读 | 不可重复读 | 幻读 | 实现机制 |
---|---|---|---|---|
READ COMMITTED | ✗ | ✓ | ✓ | 行级锁(写时加锁) |
REPEATABLE READ | ✗ | ✗ | ✗(InnoDB 通过 MVCC 避免) | 多版本并发控制(MVCC) |
死锁检测与避免:
检测:
SHOW ENGINE INNODB STATUS
查看死锁日志。避免策略:
按固定顺序访问多张表(如先更新用户表再订单表)。
设置锁超时:
innodb_lock_wait_timeout = 50
(单位:秒)。
二、JDBC 进阶实战与调优
1. 连接池精细化配置(HikariCP)
关键参数与生产建议:
参数 | 推荐值 | 作用 |
---|---|---|
| (CPU核心数 * 2) + 1 | 避免过度竞争导致线程阻塞 |
| 3000 ms | 获取连接超时快速失败 |
| 600000 ms | 回收闲置连接,释放资源 |
| 1800000 ms | 强制刷新连接,避免数据库端超时断开 |
监控集成:
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:mysql://localhost:3306/appdb");
config.setMetricRegistry(Metrics.globalRegistry); // 对接监控系统
2. 批处理与分页优化
批量插入性能对比:
try (PreparedStatement ps = conn.prepareStatement("INSERT INTO log (msg) VALUES (?)")) { for (int i = 0; i < 10000; i++) { ps.setString(1, "log_" + i); ps.addBatch(); // 添加批处理 if (i % 1000 == 0) { ps.executeBatch(); // 分批次提交 } } ps.executeBatch(); // 提交剩余数据
}
效果:万级数据插入耗时从 30s → 3s(提升 10 倍)。
分页优化方案:
深度分页问题:
LIMIT 1000000, 20
导致全表扫描 ❌优化方案:
SELECT * FROM orders WHERE id > 1000000 LIMIT 20; -- 基于有序主键
三、多线程与异步处理实战
1. 线程池管理数据库操作
配置线程池执行 JDBC 任务:
ExecutorService pool = Executors.newFixedThreadPool(10);
pool.submit(() -> { try (Connection conn = dataSource.getConnection(); PreparedStatement ps = conn.prepareStatement("UPDATE account SET balance = balance - ? WHERE id = ?")) { ps.setDouble(1, amount); ps.setInt(2, fromId); ps.executeUpdate(); }
});
注意事项:
每个线程使用独立
Connection
(避免线程安全问题)。事务边界控制在单线程内(跨线程事务需分布式事务支持)。
2. 异步 Servlet 提升吞吐量
@WebServlet(urlPatterns = "/report", asyncSupported = true)
public class ReportServlet extends HttpServlet { protected void doGet(HttpServletRequest req, HttpServletResponse resp) { AsyncContext ctx = req.startAsync(); CompletableFuture.runAsync(() -> { generateReport(); // 耗时操作 ctx.getResponse().getWriter().write("Report Generated"); ctx.complete(); }); }
}
优势:释放 Tomcat 线程池,支撑更高并发。
四、分布式架构设计与实战
1. 读写分离与数据分片
MySQL 读写分离配置:
graph LR A[应用] -->|写操作| B[Master] A -->|读操作| C[Slave1] A -->|读操作| D[Slave2] B -->|数据同步| C B -->|数据同步| D
代码路由实现:
public class DynamicDataSource extends AbstractRoutingDataSource { @Override protected Object determineCurrentLookupKey() { return TransactionSynchronizationManager.isCurrentTransactionReadOnly() ? "slave" : "master"; }
}
2. 分布式事务解决方案
Seata AT 模式流程:
事务协调器(TC)全局事务注册。
业务执行 SQL 前生成快照(UNDO_LOG)。
分支事务提交,释放本地锁。
全局事务提交/回滚时异步清理 UNDO_LOG。
代码整合:
@GlobalTransactional
public void placeOrder(Order order) { inventoryService.deductStock(order.getItems()); // 分支事务 orderDao.save(order); // 分支事务
}
五、性能监控与故障排查
1. 监控指标体系
监控层 | 工具 | 关键指标 |
---|---|---|
数据库 | Prometheus + Grafana | QPS、慢查询率、连接池活跃数 |
JVM | VisualVM | GC 时间、堆内存使用率 |
应用日志 | ELK Stack | 错误日志、慢请求追踪 |
2. 慢 SQL 排查流程
启用慢查询日志:
SET GLOBAL slow_query_log = ON; SET long_query_time = 1; -- 阈值1秒
分析执行计划:
EXPLAIN SELECT * FROM orders WHERE status = 'PENDING';
优化索引或重写 SQL。
六、总结与知识图谱
核心能力提升点:
模块 | 关键技术 | 企业级应用 |
---|---|---|
MySQL 高级 | 索引优化、事务隔离、SQL 调优 | 支撑百万级数据查询响应 <50ms |
JDBC 进阶 | 连接池调优、异步批处理 | 吞吐量提升至 10K+ TPS |
分布式架构 | 读写分离、Seata 事务 | 高可用集群容灾设计 |
学习路线图:
graph LR A[基础] --> B[Servlet/JSP] B --> C[JDBC/连接池] C --> D[会话管理] D --> E[安全防护] E --> F[高并发架构] F --> G[分布式系统]
“性能优化是持续过程,监控是优化的眼睛,架构是系统的骨架”
实战挑战:
为订单表设计复合索引,优化
WHERE user_id=? AND status=?
查询。用 HikariCP 替换 C3P0,对比 1000 并发下性能差异。
基于 Seata 实现跨服务转账(账户服务→支付服务)。