您好,欢迎访问数据库运维|优化|安装|迁移|服务官网!
13261661949
Java数据库优化,从索引到连接池的全面实践-数据资讯-数据库运维|优化|安装|迁移|服务_uDBok.com

新闻动态

联系我们

Java数据库优化,从索引到连接池的全面实践-数据资讯-数据库运维|优化|安装|迁移|服务_uDBok.com

地址:北京市昌平区高新经济开发区
手机:13261661949

咨询热线13261661949

Java数据库优化,从索引到连接池的全面实践

发布时间:2026-09-10 19:41:00人气:1240

上周帮一个电商客户排查线上问题,订单查询接口平均耗时1.8秒,数据库CPU直接飙到90%。打开慢查询日志,看到一条SQL扫了800万行,只为查一个订单状态。索引没建全,连接池参数还是默认,这性能能好才怪。Java开发者天天和数据库打交道,但真正把优化做到位的人不多。今天就把这些年踩过的坑和实战经验一次说透。

Java数据库优化,从索引到连接池的全面实践

先聊索引,这是数据库优化的第一道防线。很多人只给WHERE条件字段加普通索引,就以为完事。实际业务里,联合索引、覆盖索引、最左前缀原则这些才是关键。比如之前的电商项目,订单表有订单号、用户ID、状态、创建时间四个字段,查询条件常是“用户ID+状态+时间范围”。如果只给用户ID建索引,MySQL还要回表查状态和时间,性能自然上不去。正确的做法是建联合索引(userid, status, createtime),查询直接走索引覆盖,省掉回表。但要注意联合索引的字段顺序,区分度高的放前面,经常等值查询的放前面,需要根据业务调整。还有个细节,索引列上尽量不要做函数操作,比如WHERE DATE(createtime)='2024-01-01'会导致索引失效,应该写成createtime >= '2024-01-01' AND createtime < '2024-01-02'。

再说说慢查询日志的排查方法。很多团队线上环境根本没打开慢查询日志,出了问题全靠猜。我建议不管项目大小,都要打开这个开关,把longquerytime设成1秒,定期分析。有次帮金融客户优化,批量导入接口跑了20分钟,打开慢查询日志一看,居然是循环里一条一条INSERT,每次都提交事务,这能不慢吗?改成批量插入,用JDBC的addBatch和executeBatch,一次插入500条记录,再加上rewriteBatchedStatements=true,时间直接从20分钟降到40秒。这类问题光看代码很难发现,必须结合日志和监控才能定位。

连接池这块,很多人还是用默认配置。Druid默认初始连接数5,最大活跃数20,HikariCP稍微好点但也不够灵活。关键是要理解连接池参数背后的逻辑。maximumPoolSize设太小,高并发下线程都在排队等连接,吞吐量上不去;设太大,数据库连接数有限,连接超时反而更频繁。我一般建议根据数据库maxconnections和业务峰值来算,比如MySQL默认151个连接,业务里还有后台任务和监控在用,应用连接池最大连接数别超过100。还有connectionTimeout和idleTimeout,这两个参数要根据业务场景调,比如定时任务多的话,idleTimeout设短一点,避免空闲连接占用资源。

事务优化是很多人忽略的点。Java里用Spring管理事务很方便,但方便容易让人麻痹。有次看同事的代码,一个方法里调了三个Service方法,每个方法都标了@Transactional,结果一个请求开了三个事务,每个事务都持有数据库连接,性能能好?正确做法是事务尽量短,只在真正需要原子操作的代码块上加事务。还有隔离级别,默认的REPEATABLEREAD在MySQL里会加间隙锁,并发插入时容易死锁,如果业务对一致性要求不是特别高,可以降到READCOMMITTED,性能提升明显。

SQL优化还有个大杀器,就是分页查询。用LIMIT 200, 20这种写法,MySQL还是要扫描前20万行,越到后面越慢。优化方案有两种:一种是延迟关联,先查出主键ID,再JOIN原表取数据;另一种是记录上次查询的一条ID,用WHERE id > ? LIMIT 20这种方式做翻页。我之前优化一个后台管理系统的用户列表,数据量300万,原来翻到100页要3秒,改成ID游标方式后,任意一页都在50毫秒以内。这种优化对用户体验提升非常明显,尤其是管理后台这种操作频繁的场景。

说下压测和监控。优化做完了,效果怎么样,必须用数据说话。我一般用JMeter或wrk做压测,观察吞

推荐资讯

13261661949