注册

使用dpi获取表的全部数据比mysql慢6倍左右

DM_222193 2025/10/17 282 3

为提高效率,提问时请提供以下信息,问题描述清晰可优先响应。
【DM版本】:--03134284368-20250430-272000-20149 Pack1
【操作系统】:银河麒麟V10
【CPU】:Intel@ Xeon(R)Gold 5218 CPU @ 2.30GHz x32
【问题描述】*:使用如下表进行测试,
表字段:bigint,bigint,bigint,blob,bigint,int
使用达梦管理工具为表随机生成10000条数据,blob字段生成的随机值长度为2000字节。
在mysql及dm中分别建立这表及其数据(两种数据库部署在同一服务器),分别在数据库服务器本机,远程机器对其进行select *查询,达梦使用的程序参考《DM8程序员手册》通过达梦dpi编写,查询耗时结果如下,单位为ms:
数据库 本地 远程
DM 60 1211
MySql 66 214

可以看出达梦在本地查询时耗时与mysql相近,但在远程查询时,耗时明显增加,达到其在本地耗时20倍,而Mysql则没有这么大的差异,两个数据库远程测试所用的机器是同一台。但在远程测试的机器上使用达梦管理工具查询该表,其耗时与mysql又差不多,在240ms左右。

请问这种情况的原因是什么?如何解决dpi程序的性能问题?

dpi测试程序如下:
#include "DPI.h"
#include "DPIext.h"
#include "DPItypes.h"
#include <QElapsedTimer>
#include <iostream>

//函数检查及错误信息显示
#define DPIRETURN_CHECK(rt, hndl_type, hndl) if(!DSQL_SUCCEEDED(rt)&&rt!=DSQL_NO_DATA){dpi_err_msg_print(hndl_type, hndl);return rt;}
#define FUN_CHECK(rt) if(!DSQL_SUCCEEDED(rt)&&rt!=DSQL_NO_DATA){goto END;}

dhenv henv; /* 环境句柄 /
dhcon hcon; /
连接句柄 /
dhstmt hstmt; /
语句句柄 /
dhdesc hdesc; /
描述符句柄 /
dhloblctr hloblctr; /
lob类型控制句柄 /
DPIRETURN rt; /
函数返回值 */

void dpi_err_msg_print(sdint2 hndl_type, dhandle hndl)
{
sdint4 err_code;
sdint2 msg_len;
sdbyte err_msg[SDBYTE_MAX];
//获取错误信息字段
/* dpi_get_diag_field(hndl_type, hndl, 1, DSQL_DIAG_MESSAGE_TEXT, err_msg, sizeof(err_msg), NULL);
printf("err_msg = %s\n", err_msg);*/
//获取错误信息集合
dpi_get_diag_rec(hndl_type, hndl, 1, &err_code, err_msg, sizeof(err_msg), &msg_len);
std::cout << "err msg: " << err_msg << std::endl;
}

int main(int argc, char argv[])
{
std::string server = "192.168.101.8";
std::string user = "SYSDBA";
std::string passwd = "gf123456";
auto rt = dpi_alloc_env(&henv);
//申请环境句柄
DPIRETURN_CHECK(rt, DSQL_HANDLE_ENV, henv);
//申请连接句柄
rt = dpi_alloc_con(henv, &hcon);
DPIRETURN_CHECK(rt, DSQL_HANDLE_DBC, hcon);
//连接数据库服务器
rt = dpi_login(hcon, (sdbyte
)(server.data()), (sdbyte*)(user.data()), (sdbyte*)(passwd.data()));
DPIRETURN_CHECK(rt, DSQL_HANDLE_DBC, hcon);

sdint8 c1 = 0; //与字段匹配的变量,用于获取字段值
sdint8 c2 = 0;
sdint8 c3 = 0;
sdint8 c5 = 0;
sdint4 c6 = 0;

slength c1_ind = 0; //缓冲区
slength c2_ind = 0;
slength c3_ind = 0;
slength c5_ind = 0;
slength c6_ind = 0;
slength c4_ind = 0;
ulength row_num; //行数
ulength rows = 0;

//分配语句句柄
DPIRETURN_CHECK(dpi_alloc_stmt(hcon, &hstmt), DSQL_HANDLE_STMT, hstmt);
DPIRETURN_CHECK(dpi_alloc_lob_locator(hstmt, &hloblctr), DSQL_HANDLE_LOB_LOCATOR, hloblctr);

sdbyte *tmpbuf = nullptr;
slength val_len;
slength len;

DPIRETURN_CHECK(dpi_bind_col(hstmt, 1, DSQL_C_SBIGINT, &c1, sizeof(c1), &c1_ind), DSQL_HANDLE_STMT, hstmt);
DPIRETURN_CHECK(dpi_bind_col(hstmt, 2, DSQL_C_SBIGINT, &c2, sizeof(c2), &c2_ind), DSQL_HANDLE_STMT, hstmt);
DPIRETURN_CHECK(dpi_bind_col(hstmt, 3, DSQL_C_SBIGINT, &c3, sizeof(c3), &c3_ind), DSQL_HANDLE_STMT, hstmt);
DPIRETURN_CHECK(dpi_bind_col(hstmt, 4, DSQL_C_LOB_HANDLE, &hloblctr, sizeof(hloblctr), &c4_ind), DSQL_HANDLE_STMT, hstmt);
DPIRETURN_CHECK(dpi_bind_col(hstmt, 5, DSQL_C_SBIGINT, &c5, sizeof(c5), &c5_ind), DSQL_HANDLE_STMT, hstmt);
DPIRETURN_CHECK(dpi_bind_col(hstmt, 6, DSQL_C_SLONG, &c6, sizeof(c6), &c6_ind), DSQL_HANDLE_STMT, hstmt);

std::string selectSql = "select * from test_table";
dpi_exec_direct(hstmt, (sdbyte*)(selectSql.data()));
QElapsedTimer time;
time.start();
std::cout << "select result begin" << std::endl;
for(rt=dpi_fetch(hstmt, &row_num); DSQL_SUCCEEDED(rt)&&rt!=DSQL_NO_DATA; rt=dpi_fetch(hstmt, &row_num))
{
//获取大字段长度
rt = dpi_lob_get_length(hloblctr, &len);
tmpbuf = new sdbyte [len];
DPIRETURN_CHECK(rt, DSQL_HANDLE_LOB_LOCATOR, hloblctr);
rt = dpi_lob_read(hloblctr, 1, DSQL_C_BINARY, len, tmpbuf, len, &val_len);
rows++;
delete []tmpbuf;
}
std::cout << "select finished,time cost :" << time.elapsed() << ", row num: " << rows << std::endl;

// //断开连接
// rt = dpi_logout(hcon);
// DPIRETURN_CHECK(rt, DSQL_HANDLE_DBC, hcon);
// //释放连接句柄和环境句柄
// rt = dpi_free_con(hcon);
// DPIRETURN_CHECK(rt, DSQL_HANDLE_DBC, hcon);
// rt = dpi_free_env(henv);
// DPIRETURN_CHECK(rt, DSQL_HANDLE_ENV, henv);
MainWindow w;
w.show();
return a.exec();
}

回答 0
暂无回答
扫一扫
联系客服