2014-09-30 56 views
0
子功能的C++

代码如何使用MySQL加速C++ for循环代码转换成查询

插入数据到MySQL

bool mysqlinsert2(int sourceindex,int targetindex,string source,string target) 
    { 
     MYSQL *conn_ptr; 
     conn_ptr = mysql_init(NULL); 

     if(!conn_ptr) 
     { 
      fprintf(stderr,"mysql_init failed\n"); 
      //return EXIT_FAILURE; 
     } 

     conn_ptr = mysql_real_connect(conn_ptr,"localhost","root","nlpgroup","testdb",0,NULL,0); 

     if(conn_ptr) 
     { 
      int abc; 
      char sql_buffer[500] = {0}; 
      sprintf(sql_buffer,"insert into EM2 (sourceindex,targetindex,source,target) values(\"%d\",\"%d\",\"%s\",\"%s\")",sourceindex,targetindex,source.c_str(),target.c_str()); 
      if((abc = mysql_query(conn_ptr,sql_buffer))) 
      { 
       printf("error code:%s\n",mysql_error(conn_ptr)); 
      } 
      mysql_close(conn_ptr); 
      return true; 
      //connection succees 
     } 
     else 
     { 
      printf("Error code: %d %s %s\n",mysql_errno(conn_ptr),mysql_sqlstate(conn_ptr),mysql_error(conn_ptr)); 
      mysql_close(conn_ptr); 
      return false; 
      //return EXIT_SUCCESS; 
     } 
    } 

用于运行循环和输入for循环索引和值转换成代码MySQL的通过调用函数mysqlinsert2

void write_token_to_data() 
    { 
     typedef double* DynamicMatrix[l+m]; 
     // DynamicMatrix Count; 
     typedef double* DynamicMatrix2[l+m]; 
     //DynamicMatrix2 Prob; 
     for(int i=0; i<(l+m); i++) 
     { 
      for(int j=0; j<(l+m); j++) 
      { 
       if(mysqlinsert2(i,j,combine[i],combine[j])) 
       { 
        cout<<"insert OK!!"<<endl; 
       } 
       else 
       { 
        cout<<"insert failed"<<endl; 
       } 


      } 
     } 

    }//end of function 

当MySQL插入确定程序将返回“插入好!!” 所以,这是我的问题

这些查询可能是直到30000 * 30000次 ,我想知道如何加快这个,也许我可以优化MySQL的设置或改变在C++编写代码,我希望它有相同的结果

回答

2

一对夫妇的言论:

  • 招开你的mysqlinsert方法以外关闭MySQL连接。打开一个连接是一个缓慢的操作,所以这样做是有意义的,只有一次,只有在完成之前连接丢失才重新打开它;
  • 使用准备好的SQL语句也应该加快速度;
  • 考虑使用批量插入,以便一次插入N行(例如,尝试N = 100)。
+0

批量插入非常重要的是如何能保持该值,直到循环继续? – 2014-09-30 06:41:15

+0

你的意思是递增价值?例如,您可以生成要插入的行数组(以您认为合适的方式更改数值),然后返回对应于最后一个插入行的值。 – Ashalynd 2014-09-30 08:40:13

2

您正在为每个插入打开一个新的mysql连接,这会严重影响您的性能。打开连接并保持打开状态,直到完成所有插入。打开一个新的连接有很大的开销。

还有与事务相关的开销,所以您也很可能想要为每个事务执行多次插入。有关详细信息,请参阅本:using transactions

+0

我曾尝试将mysql连接移出此功能,并且可能在10,20次后插入错误 – 2014-09-30 06:31:28

+1

错误是什么? – krobertson 2014-09-30 06:34:17

+0

我会尝试交易和批量插入第一,是任何样品,如循环插入? – 2014-09-30 06:43:25

2

一些改进可以使:

  1. 广场这两个函数在一个类中,保持MYSQL *conn_ptr作为该类的成员字段。那么你的mysqlinsert2函数不需要每次创建和销毁连接。

    class MyInserter { 
    public: 
        MyInserter() { 
        conn_ptr = mysql_init(NULL); 
        if (!conn_ptr) throw ...; 
        conn_ptr = mysql_real_connect(conn_ptr, ...); 
        if (!conn_ptr) throw ...; 
        } 
        ~MyInserter() { 
        mysql_close(conn_ptr); 
        } 
        bool mysqlinsert2(...) { ... } 
        void write_token_to_data() { ... } 
    
    private: 
        MYSQL *conn_ptr; 
    } 
    
  2. 使用prepared statementsbound parameters。这不仅可以加快查询速度,还可以防止SQL注入攻击(即某人将引号字符放入要插入的字符串中)。

  3. 而不是使用char sql_buffer[500]sprintf,请考虑使用std::ostringstream。这样可以避免缓冲区溢出,并可以提高代码的可读性。注意下面的代码会改变,如果你在上面干什么(2),以及:

    std::ostringstream out; 
    out << "insert into EM2 (sourceindex,targetindex,source,target) values(\"" << sourceindex << "\",\"" << targetindex << "\",\"" << source << "\",\"" << target << "\")""; 
    std::string sql_string = out.str(); 
    ... mysql_query(conn_ptr, sql_string.c_str()) ...