JDBC明显快于OCCI。我应该感到惊讶吗?

时间:2017-05-30 20:06:18

标签: java c++ oracle jdbc

我对比较OCCI(Oracle C ++调用接口)和旧JDBC的性能测试感到非常惊讶。

以下是代码:

#include <iostream>
#include <cstdlib>
#include <occi.h>

using namespace oracle::occi;
using namespace std;

const string username   = "system";
const string password   = "******";
const string url        = "(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521)))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=XE)))";
const string sql        = "select * from CREDITO.movtos_cuentas";

int main(int argc, char** argv) {

    cout << "Oracle Connectivity" << endl;

    Environment *env = Environment::createEnvironment(Environment::DEFAULT);
    Connection *conn = env->createConnection(username, password, url);
    Statement *stm = conn->createStatement(sql);
    ResultSet *rs = stm->executeQuery();

    unsigned long count = 0;

    while (rs->next()) {
        count++;
    }

    stm->closeResultSet(rs);
    conn->terminateStatement(stm);
    env->terminateConnection(conn);
    Environment::terminateEnvironment(env);

    cout << "Registros na CREDITO.MOVTOS_CUENTAS: " << count << endl;

    return 0;
}

这是Java代码:

package oraconnect.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class OraconnectJdbc {

    public static void main(String[] args) {
        Connection conn = null;
        Statement stm = null;
        ResultSet rs = null;

        try {
            Class.forName("oracle.jdbc.driver.OracleDriver");
            conn = DriverManager.getConnection(
                    "jdbc:oracle:thin:@127.0.0.1:1521:xe", "system", "******");
            stm = conn.createStatement();
            rs = stm.executeQuery("select * from CREDITO.movtos_cuentas");
            long count = 0;
            while (rs.next()) {
                count++;
            }

            System.out.printf("Registros na CREDITO.MOVTOS_CUENTAS: %d\n", count);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (rs != null) {
                try {
                    rs.close();
                } catch (SQLException e) {
                    //Ignore
                }
            }
            if (stm != null) {
                try {
                    stm.close();
                } catch (SQLException e) {
                    //Ignore
                }
            }
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    //Ignore
                }
            }
        }
    }
}

执行:

C ++版

time LD_LIBRARY_PATH=/home/eduardo/Private/Oracle/instantclient_11_2/. ./oraconnect

Java版

time java -jar oraconnect-jdbc.jar -cp lib/oracle-driver-11.2.0.3.jar

C ++结果:

real    1m29.392s
user    0m32.788s
sys     0m20.812s

Java结果:

real    0m28.404s
user    0m12.076s
sys     0m4.236s

结论:

Java明显快于C ++

我想知道我是否犯了错误或者在C ++版本中使用了一些不好的做法。有人能帮我理解这个结果吗?

1 个答案:

答案 0 :(得分:0)

当你测量时间时,差异是有效的。 如果你想了解它们为什么不同,你需要将整个时间分成几个部分,看看它们是相似还是不同。并了解差异的原因。 这可以通过许多不同的方法来完成,例如跟踪或取样二进制文件上的调用堆栈,在网络层或其他许多方法上执行tcpdump。 一个非常方便的方法是在Oracle数据库中启用SQL_TRACE - 在那里您可以获得大量花费时间的信息。关于启用SQL_TRACE的方法的一个很好的介绍是https://oracle-base.com/articles/misc/sql-trace-10046-trcsess-and-tkprof。 这些跟踪文件包含大量数据,难以阅读,尤其是在开始时。有几种工具(大多数称为&#34; Profiler&#34;)可用于处理这些文件。主要产品(从我的角度来看)是 Method-R Profiler - 但是这需要花钱,你可以试试https://antognini.ch/2017/03/tvdxtat-4-0-beta-11/

没有任何进一步的信息,没有人能分辨出性能差异的原因。但是使用可用的工具,您可以识别它们。那么你要么比另一个更快地接受一个解决方案,要么修复它。

修改 我将举一个例子: 除了许多其他原因,默认行为也有所不同: OCCI一次提取2行: Accessing Oracle Database Using C++

  

默认情况下,启用预取并且数据库会获取额外的数据   一直排。

但是jdbc的结果集为10: Database JDBC Developer's Guide - Result Set

  

默认情况下,当Oracle JDBC运行查询时,它会检索结果集   数据库游标一次10行。

因此,使用OCCI的网络往返次数比使用jdbc要多5倍。

这只是一个例子 - 它可能是你观察的原因。当然,你需要测量,而不是猜测或要求猜测。