我的是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不是自己有缓存么,,怎么会这么慢的...
我现在已经找出问题就是在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不是自己有缓存么,,怎么会这么慢的...
实际上我执行的这1000条语句,都是同样的一条sql语句..我现在在做压力测试..
实际上我现在的程序时在linux操作系统下执行的,具体环境是lighttpd+fastcgi+我的C程序
我把代码注释起来找,就是发现在mysql_real_query,把这语句注释起来,1000条请求不要1秒就响应了
我发单个请求,包括查询数据库,响应很快(我没算具体花费了多少ms),当然单条请求人工感觉不出来的...
看你的语句构造方式,似乎没有用到动态绑定,你使用动态绑定试试,免去次次解析的时间。
可能用到下述API:
mysql_stmt_init
mysql_stmt_prepare
我做测试的时候是用同一个sql语句,但实际上,查询的可不是一条记录!!
{
//输出查询数据
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;}
if(mysql_real_query(m_mysql, sql, len)!=0)
{
char* out = "";
strcpy(out, mysql_error(m_mysql));
return res;
}就在这里...效率低啊..
还有一个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大小吧。
就我对Connector/J的了解,预编译帮不了什么忙,C这边应该一样
mysql_real_query是需要时间来执行的,我也知道,不过我现在的问题就是我的程序在执行它的时候,好像阻塞了一样,太慢了,1000条查询就要1分钟以上,那肯定是不行额