问题描述
我检查了日志, 它在可接受的时间内执行但是为了执行下一条语句需要时间来准备下一条语句
这里是日志
2021-03-01T12:35:42.008614Z 84 Prepare SELECT * from table where id=?
2021-03-01T12:35:42.008810Z 84 Execute SELECT * from table where id=4
2021-03-01T12:35:42.012826Z 84 Close stmt
2021-03-01T12:35:42.033090Z 84 Prepare SELECT * from table where id=?
2021-03-01T12:35:42.033279Z 84 Execute SELECT * from table where id=5
2021-03-01T12:35:42.033860Z 84 Close stmt
2021-03-01T12:35:42.054576Z 84 Prepare SELECT * from table where id=?
2021-03-01T12:35:42.054792Z 84 Execute SELECT * from table where id=6
2021-03-01T12:35:42.055372Z 84 Close stmt
时间差可能看起来不大,但是这个语句要执行大约 1200+ 次,所以最后的延迟太多了
有什么办法可以减少转换时间(close 语句和下一个 prepare 语句之间的时间)?
中间没有语句或代码行导致任何时间延迟,循环中是单个语句
:更新->
通过在 application.yml 文件中启用 CachePrepStmt
属性,我设法减少了转换时间
所以新的转换时间大约是 0.1 毫秒,但现在执行时间是 20 毫秒
怎么会这样,有什么想法吗?
这里是新的日志语句
2021-03-02T06:20:51.249367Z 59 Execute SELECT * from table where id=5
2021-03-02T06:20:51.269273Z 59 Reset stmt
2021-03-02T06:20:51.269385Z 59 Execute SELECT * from table where id=6
2021-03-02T06:20:51.289372Z 59 Reset stmt
2021-03-02T06:20:51.289512Z 59 Execute SELECT * from table where id=7
2021-03-02T06:20:51.308678Z 59 Reset stmt
2021-03-02T06:20:51.308812Z 59 Execute SELECT * from table where id=8
2021-03-02T06:20:51.328953Z 59 Reset stmt
2021-03-02T06:20:51.329123Z 59 Execute SELECT * from table where id=9
2021-03-02T06:20:51.348447Z 59 Reset stmt
解决方法
首先,看起来您只是使用了准备好的语句。这种情况下不需要JPA,只要涉及到JDBC PreparedStatement就足够了。
其次,您可以像这样使用“in”谓词来减少工作量:
SELECT * from table where id in (4,5,6,7,8,9)
如果“id”是主键或索引字段,则会产生足够快的单个选择。但是不要忘记检查查询的长度是否合理。
另一种选择是选择一个 id 范围
SELECT * from table where id between 4 and 9
然后根据需要在客户端过滤结果,只需跳过不必要的 ID。