我的是C程序,我每接收到一个请求,就需要查询一次mysql数据库mysql数据库不在本机,在局域网的一台服务器上
我现在已经找出问题就是在mysql_real_query(),能够执行,不过实在太慢了..单条执行没问题,但我如果一次接收到1000条请求,这样那么需要执行1000次mysql_real_query(),那么效率直接降低到无法忍受..
不执行数据库操作,1000条请求响应时间为0.4s.
执行mysql_real_query(),1000条请求响应时间为70s.....查询的数据大小为1K字节左右...
这是我的查询语句
("select title, artist,lrc from lrcdb where title = '%s' and artist = '%s'", title,artist);能有什么办法优化没?mysql不是自己有缓存么,,怎么会这么慢的...

解决方案 »

  1.   

    title, artist两字段上建立了索引吗?
      

  2.   

    1000条请求响应时间70s,是指每次query要70s,还是说总共70s? 如果都加了索引,可以尝试把query_cache_limit的值另大一些。
      

  3.   

    总共执行1000条需要70s...
    实际上我执行的这1000条语句,都是同样的一条sql语句..我现在在做压力测试..
    实际上我现在的程序时在linux操作系统下执行的,具体环境是lighttpd+fastcgi+我的C程序
    我把代码注释起来找,就是发现在mysql_real_query,把这语句注释起来,1000条请求不要1秒就响应了
    我发单个请求,包括查询数据库,响应很快(我没算具体花费了多少ms),当然单条请求人工感觉不出来的...
      

  4.   


    看你的语句构造方式,似乎没有用到动态绑定,你使用动态绑定试试,免去次次解析的时间。
    可能用到下述API:
    mysql_stmt_init
    mysql_stmt_prepare
      

  5.   

    你每个cgi请求都需要用到1000条数据吗?
      

  6.   

    动态绑定?。不懂也没用过呢..动态绑定是针对相同的sql语句还是怎么样?
    我做测试的时候是用同一个sql语句,但实际上,查询的可不是一条记录!!
      

  7.   

    std::vector<LrcData>   CDataBase::QueryDb(const char* title, const char* artist)
    {
    //输出查询数据
    std::vector<LrcData> res; LrcData temp;
    temp.title = "";
    temp.artist = "";
    temp.lrc = "";
    res.push_back(temp); //查询条件为空,则不查询数据库
    if ("" == title && "" == artist)
    {
    LrcData temp;
    temp.title = "";
    temp.artist = "";
    temp.lrc = "";
    res.push_back(temp);

    return res;
    } //测试与mysql是否连通
    int conn = mysql_ping(m_mysql);
    if (0 != conn)
    {
    m_mysql = mysql_real_connect(m_mysql, m_data.m_IP, m_data.m_UserName, m_data.m_PassWord, NULL, m_data.m_Port, NULL, 0);
            mysql_select_db(m_mysql, m_data.m_DBName);
    }
    //设置mysql编码
    mysql_query(m_mysql,"SET NAMES gb2312");

    //生成sql语句,执行sql语句
    char* reSql = makeSql(title, artist);
    char *sql = new char[strlen(reSql) + 1];
    memset(sql, 0, sizeof(sql));
    strcpy(sql, reSql);
    int len =strlen(sql); if(mysql_real_query(m_mysql, sql, len)!=0)
    {
    char* out = "";
    strcpy(out, mysql_error(m_mysql));
    return res;
    }
    delete [] sql;
    sql = NULL; MYSQL_RES *result = NULL;
    MYSQL_ROW row;
    /*
        //读取查询到的信息
    if(!(result=mysql_store_result(m_mysql)))
    {
    return res;
    } while(row = mysql_fetch_row(result))
    {
    LrcData temp;
            temp.title = row[0];
    temp.artist =row[1];
    temp.lrc = row[2]; res.push_back(temp);
    } //释放记录    mysql_free_result(result);*/
    return res;}char* CDataBase::makeSql(const char* title, const char* artist)
    {
    char sql[1024];
    memset(sql, 0 ,sizeof(sql));/* //无标题, 无歌手名
    if ("" == title && "" == artist)
    {
    strcpy(sql, "select title, artist,lrc from lrcdb_copy");
    return sql;
    }
    */
    //有标题,无歌手名
    if ("" != title && "" == artist)
    {
    sprintf(sql, "select title, artist,lrc from lrcdb where title = '%s'", title);
    return sql;
    }
    //无标题,有歌手名
    if ("" == title && "" != artist)
    {
    sprintf(sql, "select title, artist,lrc from lrcdb where artist = '%s'", artist);
    return sql;
    }
    //有标题,有歌手名
    if ("" != title && "" != artist)
    {
    sprintf(sql, "select title, artist,lrc from lrcdb where title = '%s' and artist = '%s'", title,artist);
    return sql;
    }
    return sql;}
      

  8.   

    CSDN既然不能编辑自己的帖子...
    if(mysql_real_query(m_mysql, sql, len)!=0)
    {
    char* out = "";
    strcpy(out, mysql_error(m_mysql));
    return res;
    }就在这里...效率低啊..
      

  9.   


    还有一个api:
    mysql_stmt_bind_param先prepare 一个sql: 只需要prepare一次
    select title, artist,lrc from lrcdb where title = ? and artist = ?
    然后分别调用
    mysql_stmt_bind_param去绑定这两个参数,也只需要调用一次最后调用你的real_query得到结果集。这是实际的思路。
    后边每次只需要去改变你bind的这两个参数的值然后再执行real_query即可得到结果如果你不想改动程序,就调调query cache的size大小吧。
      

  10.   


    就我对Connector/J的了解,预编译帮不了什么忙,C这边应该一样
      

  11.   

    ("select title, artist,lrc from lrcdb where title = '%s' and artist = '%s'", title,artist);你的title,artist如果都一样,也就是说完全等的SQL语句的话。MYSQL会利用CACHE。不过你的 mysql_real_query() 本身还是要有开销的。MYSQL需要进行SQL语法分析,权限检查,等。这不只是MYSQL的问题,其它数据库也同样,比如你观察一下CSDN,它利用了静态页面生成来解决这种性能的问题。
      

  12.   

    不是,一个cgi请求只是做一次查询..
      

  13.   

    我知道mysql的缓存,我的title,artist,是请求数据中传递过来的,所以都不一样!
    mysql_real_query是需要时间来执行的,我也知道,不过我现在的问题就是我的程序在执行它的时候,好像阻塞了一样,太慢了,1000条查询就要1分钟以上,那肯定是不行额