如何使用MySQL将c ++ for循环代码加速到查询中

时间:2014-09-30 05:55:22

标签: c++ mysql sql

c ++子函数的代码

将数据插入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;
        }
    }

运行循环的

代码,通过调用函数mysqlinsert2

将for循环索引和值输入MySQL
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插入ok时,程序将返回&#34;插入ok !!&#34; 所以,这是我的问题

这些查询可以直到30000 * 30000次 我想知道如何加速这个,也许我可以优化MySQL设置或更改c ++中的代码,我希望它有相同的结果

3 个答案:

答案 0 :(得分:2)

几句话:

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

答案 1 :(得分:2)

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

还有与事务关联的开销,因此您也很可能希望每个事务执行许多插入操作。有关详细信息,请参阅此处:using transactions

答案 2 :(得分: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],而不是sprintfstd::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()) ...