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

时间:2010-09-22 17:36:28

标签: oracle jdbc prepared-statement

在Oracle JDBC驱动程序中,有一个用于缓存预准备语句的选项。我对此的理解是,准备好的语句由驱动程序预编译,然后进行缓存,从而提高缓存预准备语句的性能。

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

2 个答案:

答案 0 :(得分:4)

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

所以会发生什么:如果使用了准备好的Statement,并且物理连接从未见过它,它会将SQL发送到DB。根据DB之前是否已经看过该语句,它将进行硬解析或软解析。所以通常如果你有一个10连接池,你会看到10个解析,其中一个解析很难。

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

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

这基本上与中间件的一些数据源更通用地实现的功能相同(例如JBoss中的prepared-statement-cache)。只使用其中一个来避免双重缓存。

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

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

另请查看支持此功能并与FAN交互的Oracle Unified Connection Pool(UCP)。

答案 1 :(得分:3)

我认为这回答了你的问题:(对不起,它是powerpoint,但它定义了如何将准备好的语句发送到Oracle,Oracle如何将其存储在共享SQL池中,处理它等)。从Prepared语句中获得的主要性能提升是,在第1 + n次运行中,您将避免对sql语句进行硬解析。

http://www.google.com/url?sa=t&source=web&cd=2&ved=0CBoQFjAB&url=http%3A%2F%2Fchrisgatesconsulting.com%2FpreparedStatements.ppt&rct=j&q=java%20oracle%20sql%20prepared%20statements&ei=z0iaTJ3tJs2InQeClPwf&usg=AFQjCNG9Icy6hmlFUWHj2ruUsux7mM4Nag&cad=rja

Oracle(或者选择的数据库)将存储准备好的语句,java只是发送它与db将选择的相同语句(这是有限的资源,但是在没有查询的x时间之后,共享的sql将被清除esp。非常见的查询)然后需要重新解析 - 无论它是否缓存在你的java应用程序中。