代码之家  ›  专栏  ›  技术社区  ›  Ken Liu

数据库驱动程序中已编译的prepared语句是否仍需要在数据库中编译?

  •  4
  • Ken Liu  · 技术社区  · 14 年前

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

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

    2 回复  |  直到 14 年前
        1
  •  5
  •   eckes    12 年前

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

    所以发生的事情是:如果使用了一个prepared语句,而物理连接从未见过它,那么它会将SQL发送到DB。取决于DB之前是否见过该语句,它将执行硬解析或软解析。所以通常如果你有10个连接池,你会看到10个解析,其中一个是硬解析。

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

    如果在物理连接上使用的prepared语句比缓存的大小多(不同),则最长未使用的open shared游标将关闭。这会在下次再次使用该语句时导致另一个软解析,因为需要再次将SQL发送到服务器。

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

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

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

        2
  •  3
  •   Harrison    14 年前

    我认为这回答了您的问题:(对不起,这是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(或db的选择)将存储准备好的语句,java只发送它的相同的语句,db将从中选择(这是有限的资源,但在x次无查询后,共享sql将被清除,特别是非公共查询),然后将需要重新解析-无论它是否缓存在java应用程序中。