繁体   English   中英

PreparedStatement在Java中更快,db如何做到这一点?

[英]PreparedStatement is faster in Java, How db do it?

我知道PreparedStatement比Java中的Statement更快。

我不知道oracle db server是如何做到的。

PreparedStatement得到预编译在数据库服务器 - >少工作。 它减少了数据库的负担。

String sql = "SELECT * FROM users u WHERE u.id = ?";
PreparedStatement pstmt = connenction.prepareStatement(sql);
pstmt.setLong(1, userId);
pstmt.executeQuery();

查询缓存在数据库服务器中,只编译一次?
如果是,数据库服务器如何知道此查询之前执行过?
它缓存了多长时间?

查询缓存在数据库服务器中,只编译一次?

更确切地说,查询计划缓存在服务器上。 运行查询时,RDBMS首先准备计划,然后执行它。 准备计划需要解析查询,然后分析和优化它,考虑可用的索引和参与表上收集的统计信息。

如果是,数据库服务器如何知道此查询之前执行过?

通过将查询字符串与缓存中可用的其他查询进行比较。 由于您使用参数化查询,因此另一个查询在文本上是相同的。 缓存是第二大原因*使用查询参数:如果你准备这样的语句

// WRONG! Don't do it like this!
String sql = "SELECT * FROM users u WHERE u.id = "+userId;
PreparedStatement pstmt = connenction.prepareStatement(sql);

所有性能改进都将消失,因为提供不同的ID会使其成为需要新计划的不同查询。

*参数化查询的首要原因当然是避免注入攻击。

您可以将PreparedStatement视为“缓存”语句,该语句将在数据库服务器上编译一次。

创建语句时,它将被发送到数据库服务器,数据库服务器将执行常规语法检查并确定查询的有效执行计划。 这样,它可以重复使用相同的执行计划(也被缓存)用于同一语句的多次调用。

此缓存的关键是语句本身没有填充参数值。 如果在语句中显式填充了值(即,您没有使用set*方法填充它们),则将在缓存中访问新的执行计划。 这就是为什么在执行多个语句但具有不同值时最好使用预处理语句的原因。

我在我的项目中使用Data Source,其中查询缓存依赖于连接。 每个连接维护查询缓存(默认大小为10)。 这意味着如果我有5个连接,每个连接最新的10个预准备语句被缓存。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM