迭代一个有10000行的mysql结果集,耗时3.5秒.这正常吗?

Iterate a mysql resultset which has 10000 rows, it takes 3.5 seconds. Is it normal?

本文关键字:耗时 5秒 常吗 结果 mysql 一个 10000行 迭代      更新时间:2023-10-16

我使用c++和mysql++来获取结果集,并使用fetch_row()进行迭代

结果集有10000行,这个"While"循环花费了将近3.5秒。(我已经注释掉了while循环中的内容。)

这种情况正常吗?我认为它应该完成得更快!

Connection* conn = ConnPool::getSingletonPtr()->getConn();
Query qr = conn->query(sql);
SYSTEMTIME lpsystime;  
GetLocalTime(&lpsystime);  
UseQueryResult res = qr.use();
while(FryRow row = res.fetch_row())
{
    /*
    MyObject obj;
    for(int i=0; i<row.size(); i++)
    {
        obj.setValue(res.fetch_field(i).name(), row[i]);
    }
    objList->push_back(obj);
    */
}
GetLocalTime(&lpsystime);  

MyObject有属性:

 int procedureNo;
 int index;
 int employeeNo;
 int procCount;
 int state;
 int procPermission;
 int procDeadline;
 int advanceAlert;
 DateTime procTime;
 int resultFlag;
 string comment;
 int flowDirection;
 int isHideComment;
 int isTrack;
 DateTime arriveTime;
 string preNodesJsonStr;
 string nextNodesJsonStr;
 string attachStr;
 string employeeName;
 DateTime employeeBirthDay;

************************** 分支器 *****************************谢谢大家!我修改了代码,并像这样再次测量时间:

Connection* conn = ConnPool::getSingletonPtr()->getConn();
Query qr = conn->query(sql);
SYSTEMTIME lpsystime;  
GetLocalTime(&lpsystime);  // get the time before use().
UseQueryResult res = qr.use();
GetLocalTime(&lpsystime);  // get the time before While loop.

while(FryRow row = res.fetch_row())
{
        /*
        MyObject obj;
        for(int i=0; i<row.size(); i++)
        {
            obj.setValue(res.fetch_field(i).name(), row[i]);
        }
        objList->push_back(obj);
        */
}
GetLocalTime(&lpsystime);  // get the time when While loop finished.

use()函数只花费10ms。

While循环耗时1.677秒。

如果我没有注释掉while循环中的内容。

setValue()函数定义如下:

MyObject::setValue(const char * colName, const mysqlpp::String& ele)
{ 
 if(strcmp(colName,"column010") == 0)
      procedureNo = ele;
 else if(strcmp(colName,"column020") == 0)
      index = ele;
 else if(strcmp(colName,"column030") == 0)
      employeeNo = ele;
 else if(strcmp(colName,"column040") == 0)
      procCount = ele;
 else if(strcmp(colName,"column050") == 0)
      state = ele;
 else if(strcmp(colName,"column060") == 0)
      procPermission = ele;
 else if(strcmp(colName,"column070") == 0)
      procDeadline = ele;
 else if(strcmp(colName,"column080") == 0)
      advanceAlert = ele;
 else if(strcmp(colName,"column090") == 0)
      procTime = ele;
 else if(strcmp(colName,"column100") == 0)
      resultFlag = ele;
 else if(strcmp(colName,"column110") == 0)
      comment = ele;
 else if(strcmp(colName,"column120") == 0)
      flowDirection = ele;
 else if(strcmp(colName,"column130") == 0)
      isHideComment = ele;
 else if(strcmp(colName,"column140") == 0)
      isTrack = ele;
 else if(strcmp(colName,"column150") == 0)
      arriveTime = ele;
 else if(strcmp(colName,"column160") == 0)
      preNodesJsonStr = ele;
 else if(strcmp(colName,"column170") == 0)
      nextNodesJsonStr = ele;
 else if(strcmp(colName,"column180") == 0)
      attachStr = ele;
 else if(strcmp(colName,"column190") == 0)
      employeeName = ele;
 else if(strcmp(colName,"column200") == 0)
      employeeBirthDay = ele;
}

您的问题是您还测量了查询的执行时间。conn->query(sql);不执行查询。它只是构建一个Query对象。然后use方法实际执行查询。例如,在您的代码中,这一行实际上执行了查询:

UseQueryResult res = qr.use();

来自mysql++文档:

 UseQueryResult mysqlpp::Query::use ()  

执行一个可以返回行并按顺序访问行的查询。使用Use()中的一个如果内存效率很重要,则会过载。它们返回一个对象它可以逐个遍历结果记录,而不需要获取来自服务器的整个结果集。

但是请注意,即使您取出use调用,您仍然可能在循环中获得一些查询执行时间,因为use逐个提取行。因此,数据库一个元组一个元组地执行查询,并且只在从结果中取出下一个元组时才计算下一个元组。如果您真的想通过所有的结果来测量一个循环,那么您必须使用store函数。它彻底执行查询并将结果存储在一块内存中。然后,你的循环会非常快。但是,您仍然应该选择use,因为首先将所有结果存储到内存中通常只是浪费时间和内存。