oracle - 数据库驱动程序中已编译的预备语句是否仍需要在数据库中进行编译?

标签 oracle jdbc prepared-statement

在 Oracle JDBC 驱动程序中,有一个选项可以缓存准备好的语句。我对此的理解是,准备好的语句由驱动程序预编译,然后缓存,这提高了缓存的准备好的语句的性能。

我的问题是,这是否意味着数据库永远不必编译那些准备好的语句? JDBC 驱动程序是否发送一些预编译的表示形式,或者数据库本身是否仍然发生某种解析/编译?

最佳答案

当您使用隐式语句缓存(或显式语句缓存的 Oracle 扩展)时,Oracle 驱动程序将在 close() 之后缓存准备好的或可调用的语句,以便与物理连接重用。

所以发生的情况是:如果使用了准备好的语句,并且物理连接从未见过它,它会将 SQL 发送到数据库。根据数据库之前是否见过该语句,它将执行硬解析或软解析。因此,通常如果您有 10 个连接池,您将看到 10 次解析,其中之一是硬解析。

在连接上关闭语句后,Oracle 驱动程序会将已解析语句(共享游标)的句柄放入 LRU 缓存中。下次您在该连接上使用prepareStatement 时,它会找到要使用的缓存句柄,并且根本不需要发送SQL。这会导致执行时没有 PARSE。

如果在物理连接上使用的(不同的)准备好的语句多于缓存的大小,则关闭最长的未使用的打开共享游标。这会导致下次再次使用该语句时再次进行软解析 - 因为 SQL 需要再次发送到服务器。

这与一些中间件数据源更通用地实现的功能基本上相同(例如 JBoss 中的准备语句缓存)。仅使用两者之一以避免双重缓存。

您可以在此处找到详细信息:

http://docs.oracle.com/cd/E11882_01/java.112/e16548/stmtcach.htm#g1079466

另请查看支持此功能并与 FAN 交互的 Oracle 统一连接池 (UCP)。

关于oracle - 数据库驱动程序中已编译的预备语句是否仍需要在数据库中进行编译?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3772038/

相关文章:

java - 从 Oracle 数据库调用批处理脚本/Java 代码

mysql - 是否有任何 SQL 验证器可以针对多个数据库服务器检查语法?

sql - Oracle SQL 错误 : ORA-00923: From Keyword not found where expected

sql - 一个外键多列 VS 多个外键单列

java - JDBC 使用 SELECT FOR UPDATE 锁定一行,不起作用

java - JDBC 事务问题。无法使其原子性

php - mysqli_fetch_assoc()需要参数/调用成员函数bind_param()错误。如何获取并修复实际的mysql错误?

sql - 检查derby数据库中的表中是否存在自动增量

php - "No data supplied for parameters in prepared statement"

java - Prepared Statements如何比Statements更好地防止SQL注入(inject)?