我在做一个服务端计费软件,要求对于客户端发来的消息尽快响应,我用的是VC,数据库是oracle,数据库操作方法用的是ADO,我有一个VC使用ADO访问数据库的封装好的类,该类有一段是执行Sql语句查询并返回记录集的方法,代码如下:
_RecordsetPtr CRADatabase::RAExecuteRs(const char *SqlStatement)
{
// Attempt to execute a SQL statement, return the RS, and leave connection open
if (strlen(SqlStatement) > 0)
{
try
{
if (m_Connection == NULL || m_Connection->State == adStateClosed)
RAConnect(m_ConnectionString);
if (m_Recordset)
{
if (m_Recordset->State == adStateOpen)
m_Recordset->Close();
}
else
{
m_Recordset.CreateInstance(__uuidof(Recordset));
}

m_Command->ActiveConnection = m_Connection;
m_Command->CommandType = adCmdText;
m_Command->CommandText = SqlStatement;

_variant_t vNull;
vNull.vt = VT_ERROR;
vNull.scode = DISP_E_PARAMNOTFOUND;

m_Recordset = m_Command->Execute( &vNull, &vNull, adCmdText );


return m_Recordset.Detach();
}
catch(_com_error &e)
{
printf("Description = %s\n", (char*) e.Description());   
}
catch(...)
{
}
} return NULL;
}
使用的时候我先定义了这个类的实例data,使用情况如下:
         _RecordsetPtr pRecord;
CComVariant valRecord;
         char strSql[1024]="";
    strcpy(strSql,"select * from custdata where custdata.usercode = ");
strcat(strSql,"'");
strcat(strSql,userName);
strcat(strSql,"'");
pRecord = data.RAExecuteRs(strSql);
if (pRecord->adoEOF)
{
if (pRecord!=NULL)
{
pRecord->Close();
}
//该账号不存在
returncode = 1;
}
else 
{
//该账号存在
//取出密码
_bstr_t strpassword;
valRecord = pRecord->Fields->Item[_variant_t("ACCESSKEY")]->Value;
valRecord.ChangeType(VT_BSTR);
strpassword = valRecord.bstrVal;
valRecord.Clear(); double balance=0;
valRecord = pRecord->Fields->Item[_variant_t("accountbalance")]->Value;
valRecord.ChangeType(VT_R8);
*Accountbalance = valRecord.dblVal;
valRecord.Clear();
//取出客户费率编号
valRecord = pRecord->Fields->Item[_variant_t("TRFCODE")]->Value;
valRecord.ChangeType(VT_BSTR);
strtrfcode = valRecord.bstrVal;
valRecord.Clear();
//从数据集pRecord中取出有效日期
double Expirtiondate=0;
valRecord = pRecord->Fields->Item[_variant_t("ACTUALEXPDATE")]->Value;
valRecord.ChangeType(VT_DATE);
Expirtiondate = valRecord.date;
valRecord.Clear(); 我发现一个问题,可是我不知道是怎么回事,问题如下:

我设了断点和使用DWORD start =GetTickCount();这种方法来看语句的花费时间,发现 执行pRecord = data.RAExecuteRs(strSql);语句几乎没有花时间,连一毫秒都不到,可是执行if (pRecord->adoEOF)语句却花费了我50-60个毫秒,后面的
valRecord = pRecord->Fields->Item[_variant_t("ACCESSKEY")]->Value;
...
valRecord = pRecord->Fields->Item[_variant_t("accountbalance")]->Value;
...
valRecord = pRecord->Fields->Item[_variant_t("TRFCODE")]->Value;
...
用去的时间也很短,不到一毫秒,可是一旦我将语句
if (pRecord->adoEOF)
{
if (pRecord!=NULL)
{
pRecord->Close();
}
//该账号不存在
returncode = 1;
}
这个判断数据集是否为空的判断删除
却发现
valRecord = pRecord->Fields->Item[_variant_t("ACCESSKEY")]->Value;
这个操作用去了50毫秒,而后来的
valRecord = pRecord->Fields->Item[_variant_t("accountbalance")]->Value;
...
valRecord = pRecord->Fields->Item[_variant_t("TRFCODE")]->Value;
...
却一毫秒都没有用到按我的理解,情况好象就是这样:
执行Sql语句用不了一毫秒,而后来对该数据集的第一次操作(可能是判断是否为空,也可能是直接取数据),都需要50-60毫秒,再以后对该数据集的操作所花费的时间不到1毫秒。
因为我的程序对时间的要求很高,要求每次消息的处理时间控制在20毫秒一内,而数据库操作50-60毫秒的瓶颈令我无法达到要求,我想问问大家,是什么原因造成这种情况的,有没有好的解决办法,可以令我的数据库操作时间减少,谢谢各位!!!