【问题标题】:JDBC Oracle Query. Slow when executing with setInt() instead of setObject()JDBC Oracle 查询。使用 setInt() 而不是 setObject() 执行时速度慢
【发布时间】:2012-02-24 00:25:45
【问题描述】:

我有以下代码片段:

    public static void main(String[] args) throws SQLException {
    Connection c = getConnection();
    long time = System.currentTimeMillis();
    PreparedStatement ps = c.prepareStatement(sqlQuery);
    int index = 1;
    for (String param: parameters) {
        if (isInt(param)) {
            //ps.setInt(index++, Integer.parseInt(param));
            ps.setObject(index++, Integer.parseInt(param), java.sql.Types.NUMERIC , 0);
        } else {
            ps.setString(index++, param);
        }
    }
    displayResult(ps.executeQuery());
    System.out.println("It took " + (System.currentTimeMillis()-time) + ".");

    time = System.currentTimeMillis();
    Statement s = c.createStatement();
    ResultSet rs = s.executeQuery(expandParametersInStatement(sqlQuery, parameters));
    displayResult(rs);
    System.out.println("It took " + (System.currentTimeMillis()-time) + ".");
}

使用 PreparedStatement 执行的查询要慢 4000 倍。与 Statement 方法相比。它们给出相同的结果,执行顺序没有太大区别。

使用 setObject() 代替 setInt() 使 PreparedStatement 与 Statement 一样快。

有什么区别?数据库中的演员不能那么昂贵吗?数据库中的数据类型是 NUMBER(10)。我想这是使用的indeces的问题。但是,我无法使用 CAST(x AS INTEGER) 在 SQL Developer 中复制它?

谢谢。

声明是:

private static String sqlQuery = "SELECT sum(value) " +
"FROM a monat, " +
"     n jahr, " +
"     kunde kunde " +
"WHERE monat.kunde_nr IN " +
"    (SELECT DISTINCT kunde.kunde_nr " +
"     FROM MASKE_4_KUNDEN kunde " +
"     WHERE kunde.firma_nr = ? " +
"       AND kunde.verkaufsbereich_nr = ? " +
"       AND kunde.vertriebsbereich_nr BETWEEN (CASE WHEN ? <> -1 THEN ? ELSE -9999999999 END) AND (CASE WHEN ? <> -1 THEN ? ELSE 9999999999 END) " +
"       AND kunde.vertreter_nr BETWEEN (CASE WHEN ? <> -1 THEN ? ELSE -9999999999 END) AND (CASE WHEN ? <> -1 THEN ? ELSE 9999999999 END)" +
"       AND kunde.konzern_nr BETWEEN (CASE WHEN ? <> -1 THEN ? ELSE -9999999999 END) AND (CASE WHEN ? <> -1 THEN ? ELSE 9999999999 END) " +
"       AND kunde.geschaeftsjahr = ? " +
"       AND kunde.kunde_nr BETWEEN (CASE WHEN ? <> -1 THEN ? ELSE -9999999999 END) AND (CASE WHEN ? <> -1 THEN ? ELSE 9999999999 END))" +
"  AND monat.firma_nr = ? " +
"  AND monat.verkaufsbereich_nr = ? " +
"  AND monat.jahr_nr = ? " +
"  AND jahr.kunde_nr = monat.kunde_nr " +
"  AND jahr.firma_nr = monat.firma_nr " +
"  AND jahr.jahr_nr = monat.jahr_nr " +
"  AND jahr.verkaufsbereich_nr = monat.verkaufsbereich_nr " +
"  AND kunde.kunde_nr = monat.kunde_nr " +
"  AND kunde.firma_nr = monat.firma_nr";

【问题讨论】:

  • 请向我们展示实际声明
  • 为您添加了查询。但是,此问题是通用问题,与特定查询无关。
  • 如果在循环中执行相同的测试和/或切换测量顺序会发生什么?
  • 没有什么会立即跳出来。当您说“与声明相比”时,您的意思是使用文字而不是占位符的版本?在这种情况下,对包含? 的语句运行解释计划,并将其与使用文字的语句的解释计划进行比较。
  • 是的声明我的意思是我已经替换了 ?用文字。

标签: java sql performance oracle jdbc


【解决方案1】:

我们在 Oracle 数据库 10.2.0.4.0 上使用仅包含 setString() 语句的预处理语句也观察到了相同的行为。

问题已完全解决将jdbc驱动从10.2.0.3.0更新到10.2.0.4.0

【讨论】:

    【解决方案2】:

    setInt() 方法接收 int 作为第二个参数(不是 Integer)。现在,我知道自动装箱应该可以工作,但显然它并不总是有效:http://www.coderanch.com/t/550628/JDBC/java/setInt-String-int-Lost 我的猜测是它在旧版本的 JDBC 中不起作用,它在新版本中起作用,但仍然有问题...... 我会尝试使用 Integer.intValue() 看看它是否更好用!

    如果有人对此有更多意见 - 我很想听听!

    【讨论】:

    • Integer.parseInt() 返回一个int(也不清楚自动装箱如何让它变得这么慢)。
    • @Dmitri parseInt() 接收一个字符串作为参数,而 intValue 对 Integer 本身起作用(这是我所指的选项)。但当然您可以将 parseInt 与原始字符串参数一起使用,而不是创建一个 Integer 并调用它的 int-value - 您的方式更有效;)
    猜你喜欢
    • 1970-01-01
    • 2012-11-10
    • 2020-02-28
    • 1970-01-01
    • 2016-06-08
    • 2019-07-27
    • 1970-01-01
    • 2015-10-04
    • 2016-01-04
    相关资源
    最近更新 更多