【问题标题】:JDBC - Best way for perfomance of a preparedstatement with optional criteriaJDBC - 使用可选标准执行preparedstatement的最佳方式
【发布时间】:2014-04-01 03:41:33
【问题描述】:

我尝试提高我的应用程序的性能。为此,我将当前语句替换为prepared-statement 以使用oracle cash。

但我的一些查询是动态的(条件标准和表格),我想知道减少执行时间的最佳解决方案。

在stackoverflow中,我找到了两个解决方案。 首先是使用 if 语句构建查询:

if(a.equals("Test")) {
   whereClause.append ("COLUMN1 = ? ");
} 
if(b.equals("Test2")) {
   whereClause.append ("COLUMN2 = ? ");
} etc...

第二种是创建一个包含所有条件的查询,但添加“OR var is null”

where (? is null OR (COLUMN1 = ?)) AND (? is null OR (COLUMN2 = ?)) etc.

在您看来,在您知道请求可能包含 40/50 标准并且某些表格也可以是可选的情况下,最好的方法是什么。或者是否有其他解决方案。

使用的数据库是oracle,datasource和jdk 1.5。

提前感谢您的帮助。

【问题讨论】:

    标签: java performance oracle jdbc prepared-statement


    【解决方案1】:

    prepared statement 的最大优势是提前完成了查询计划(优化)。老实说,我怀疑如果你有 20 个这样的标准,而实际上只有少数几个标准被使用,那么优化会非常大。你为什么不测试一下,看看哪个最快?

    另外,我认为用它来创建一个存储过程可能是非常有利的。

    【讨论】:

    • 对不起,我的标准多于 20,这是我第一次发帖的错误。在 more 中,table 可以是更多可选的。我无法轻松测试,因为应用程序太复杂了。我更喜欢从一开始就尝试获得正确的建议。感谢您的帮助。
    【解决方案2】:

    我会将 PreparedStatement 与动态查询一起使用,而无需任何额外的逻辑。如果查询重复,JDBC 会找到以前执行的缓存语句。

    【讨论】:

    • 好的,然后我尝试使用 if 语句的第一个解决方案。 JDBC 会将最常用的查询模型放入缓存?
    • 这取决于驱动程序和DBCP是否使用。注意缓存可能会绑定连接,在新的连接中缓存会是空的
    【解决方案3】:

    我同意 Evgeniy,PreparedStatements 是要走的路。如果您有许多参数,那么使用命名参数而不是问号来维护会更容易。见:http://www.javaworld.com/article/2077706/core-java/named-parameters-for-preparedstatement.html。我已经使用了大约 20 个标准。

    【讨论】:

    • 感谢您的回答。我不知道“命名参数”
    【解决方案4】:

    First JDBC 和 Oracle 能够处理和缓存多个准备好的语句。

    第一种方法:

    if(a.equals("Test")) {
       whereClause.append ("COLUMN1 = ? ");
    } 
    if(b.equals("Test2")) {
       whereClause.append ("COLUMN2 = ? ");
    }
    

    肯定会导致更多不同的语句和数千个准备好的语句,但是每个语句在准备时都是可优化的,因为没有变量是可选的。

    第二种方法:

    where (? is null OR (COLUMN1 = ?)) AND (? is null OR (COLUMN2 = ?)) etc.
    

    将只产生一个准备好的语句,但在准备期间,查询计划需要包括所有参数都不为空的可能性。

    所以这真的变成了基准测试以及有多少可选参数的问题。如果你有太多准备好的语句,一个可能不会被缓存(但它也可能是,它很少使用,这不会影响整体性能)。

    我也不知道第二种方法中的可选参数会产生多少开销,即使它们是针对每一行进行评估的,因为优化器无法删除它们。

    最后,如果您准备了涵盖某些可选参数组合的索引,则第一种方法应该更快,因为在准备期间评估可能的索引并选择最佳索引(查询计划)。

    【讨论】:

    • 感谢您的回答。您知道缓存是否保留最常用的查询或最后执行的查询吗?因为我不清楚preparedstatement什么时候使用缓存。
    • 我认为它是两者的混合体。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-22
    • 1970-01-01
    • 2014-04-26
    • 2014-10-01
    • 2018-08-19
    • 2018-07-24
    • 2012-01-29
    相关资源
    最近更新 更多