Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/361.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PreparedStatement在Java中更快,db是如何做到的?_Java_Oracle_Jdbc_Prepared Statement - Fatal编程技术网

PreparedStatement在Java中更快,db是如何做到的?

PreparedStatement在Java中更快,db是如何做到的?,java,oracle,jdbc,prepared-statement,Java,Oracle,Jdbc,Prepared Statement,我知道PreparedStatement比Java中的语句快 我不知道oracle db server是如何做到这一点的 PreparedStatement在数据库服务器->更少的工作中预编译。 它可以减少数据库的负载 String sql = "SELECT * FROM users u WHERE u.id = ?"; PreparedStatement pstmt = connenction.prepareStatement(sql); pstmt.setLong(1, userId);

我知道PreparedStatement比Java中的语句快

我不知道oracle db server是如何做到这一点的

PreparedStatement在数据库服务器->更少的工作中预编译。 它可以减少数据库的负载

String sql = "SELECT * FROM users u WHERE u.id = ?";
PreparedStatement pstmt = connenction.prepareStatement(sql);
pstmt.setLong(1, userId);
pstmt.executeQuery();
查询缓存在数据库服务器中,并且只编译一次
如果是,数据库服务器如何知道此查询是以前执行的

它被缓存多长时间?

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

当您创建语句时,它将被发送到DB服务器,DB服务器将执行通常的语法检查并确定查询的有效执行计划。通过这种方式,它可以对同一语句的多次调用重复使用相同的执行计划(也可以缓存)

该缓存的键是语句本身,没有填充其参数值。如果在语句中显式填充值(即,不使用
set*
方法填充值),则将在缓存中访问新的执行计划。这就是为什么在执行多个具有不同值的语句时,最好使用准备好的语句

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

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

如果是,数据库服务器如何知道此查询是以前执行的

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

// WRONG! Don't do it like this!
String sql = "SELECT * FROM users u WHERE u.id = "+userId;
PreparedStatement pstmt = connenction.prepareStatement(sql);
所有性能改进都将消失,因为提供不同的
ID
将使其成为需要新计划的不同查询


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

我在项目中使用数据源,其中查询缓存依赖于连接。 每个连接都维护查询缓存(默认大小为10)。
这意味着,如果我有5个连接,每个连接会缓存最近10条准备好的语句。

JDBC驱动程序知道如何将语句传递给服务器并获得某种句柄。他如何比较字符串?他有一张上面所有问题的清单吗?有时间离开这个字符串吗?它将在缓存中保留多长时间?@lolo它不需要是一个列表-哈希表工作得更好。查询字符串是存储在表中的查询计划的一个很好的哈希键。那么,何时从哈希表中删除此字符串?@lolo我不知道Oracle保留缓存查询计划的规则的细节,但通常缓存项在一段时间内没有使用时会被丢弃(这取决于服务器的负载)或哈希表开始占用太多内存的时间。我相信DBA可以配置这两个参数,但我不确定,因为我已经有七年没有使用Oracle了。谢谢。您的回答非常有帮助!