为什么 JPA 需要时间从关闭的 stmt 过渡到下一个 Prepare stmt
Why JPA takes time for transition from close stmt to next Prepare stmt
我有 JPA 语句,在执行时执行简单查询。
我检查了日志,
它在可接受的时间内执行,但要执行下一条语句,需要时间来准备下一条语句
这是日志
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+次左右,所以最后的延迟实在是太大了
有什么方法可以减少转换时间(关闭语句和下一个准备语句之间的时间)?
中间没有任何语句或代码行导致任何时间延迟,它是循环中的单个语句
:更新->
我通过在 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”是主键或索引字段,这会导致足够快的单个 select。但不要忘记检查查询的长度是否合理。
另一种选择是select一系列ID
SELECT * from table where id between 4 and 9
然后根据需要在客户端过滤结果,跳过不需要的id。
我有 JPA 语句,在执行时执行简单查询。
我检查了日志, 它在可接受的时间内执行,但要执行下一条语句,需要时间来准备下一条语句
这是日志
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+次左右,所以最后的延迟实在是太大了
有什么方法可以减少转换时间(关闭语句和下一个准备语句之间的时间)?
中间没有任何语句或代码行导致任何时间延迟,它是循环中的单个语句
:更新->
我通过在 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”是主键或索引字段,这会导致足够快的单个 select。但不要忘记检查查询的长度是否合理。
另一种选择是select一系列ID
SELECT * from table where id between 4 and 9
然后根据需要在客户端过滤结果,跳过不需要的id。