JDBC 明显快于 OCCI。我应该感到惊讶吗?
Posted
技术标签:
【中文标题】JDBC 明显快于 OCCI。我应该感到惊讶吗?【英文标题】:JDBC significantly faster than OCCI. Should I be surprised? 【发布时间】:2017-05-30 20:06:17 【问题描述】:我对比较 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++ 版本中犯了错误或使用了一些不好的做法。谁能帮我理解这个结果?
【问题讨论】:
他发布了一个问题,你无法相信接下来会发生什么! NathanOliver,结果已发布。 结论 - 你第二个运行的速度更快,因为一堆数据已经从磁盘中提取并位于 SGA 中。 为什么说“旧的 JDBC”? Oracle 通过添加新特性和性能优化不断改进其 JDBC 驱动程序。 感谢您改进问题的指导,但我希望您专注于寻找问题的解决方案,这是最重要的。我明白这足以理解并尝试回应。我们都会通过解决问题的方法获胜。 【参考方案1】:在您测量时间时,差异是有效的。 如果您想了解它们为什么不同,则需要将整个时间分成一些部分,看看它们是相似还是不同。并了解差异的原因。 这可以通过许多不同的方法来完成,例如跟踪或采样二进制文件上的调用堆栈,在网络层执行 tcpdump 或许多其他方法。 一个非常方便的方法是在 Oracle 数据库中启用 SQL_TRACE - 在那里您可以获得很多花费时间的信息。关于启用 SQL_TRACE 的方法的一个很好的介绍是 https://oracle-base.com/articles/misc/sql-trace-10046-trcsess-and-tkprof。 这些跟踪文件包含大量数据并且难以阅读,尤其是在开始时。有几种工具(大多数称为“Profiler”)可用于处理这些文件。领先的产品(从我的角度来看)是 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 倍。
这只是一个例子——它可能是你观察的原因,也可能不是。可以肯定的是,您需要衡量,而不是猜测或要求猜测。
【讨论】:
谢谢马丁,我同意你的建议很好。但这是一个非常简单的测试,只有一个本地数据库连接和一个表中的简单 SELECT。令我惊讶的是,使用 OCCI(C++ 的 Oracle 解决方案),Java 比 C++ 快 3 倍。对我来说,这是一个令人惊讶的结果。 我怀疑Oracle的解决方案(OCCI)是否是一个好的解决方案。 嗨马丁,实际上当我均衡获取大小时,差异是近似的,但 JDBC 仍然优于 OCCI。 OCCI = 19s 和 JDBC = 12s。以上是关于JDBC 明显快于 OCCI。我应该感到惊讶吗?的主要内容,如果未能解决你的问题,请参考以下文章
我应该对 API 密钥使用 Authorization 标头吗