手机
当前位置:查字典教程网 >编程开发 >mysql数据库 >提高MySQL 查询效率的三个技巧第1/2页
提高MySQL 查询效率的三个技巧第1/2页
摘要:MySQL由于它本身的小巧和操作的高效,在数据库应用中越来越多的被采用.我在开发一个P2P应用的时候曾经使用MySQL来保存P2P节点,由于...

MySQL由于它本身的小巧和操作的高效,在数据库应用中越来越多的被采用.我在开发一个P2P应用的时候曾经使用MySQL来保存P2P节点,由于P2P的应用中,结点数动辄上万个,而且节点变化频繁,因此一定要保持查询和插入的高效.以下是我在使用过程中做的提高效率的三个有效的尝试.

l使用statement进行绑定查询

使用statement可以提前构建查询语法树,在查询时不再需要构建语法树就直接查询.因此可以很好的提高查询的效率.这个方法适合于查询条件固定但查询非常频繁的场合.

使用方法是:

绑定,创建一个MYSQL_STMT变量,与对应的查询字符串绑定,字符串中的问号代表要传入的变量,每个问号都必须指定一个变量.

查询,输入每个指定的变量,传入MYSQL_STMT变量用可用的连接句柄执行.

代码如下:

//1.绑定

boolCDBManager::BindInsertStmt(MYSQL*connecthandle)

{

//作插入操作的绑定

MYSQL_BINDinsertbind[FEILD_NUM];

if(m_stInsertParam==NULL)

m_stInsertParam=newCHostCacheTable;

m_stInsertStmt=mysql_stmt_init(connecthandle);

//构建绑定字符串

charinsertSQL[SQL_LENGTH];

strcpy(insertSQL,"insertintoHostCache(SessionID,ChannelID,ISPType,"

"ExternalIP,ExternalPort,InternalIP,InternalPort)"

"values(?,?,?,?,?,?,?)");

mysql_stmt_prepare(m_stInsertStmt,insertSQL,strlen(insertSQL));

intparam_count=mysql_stmt_param_count(m_stInsertStmt);

if(param_count!=FEILD_NUM)

returnfalse;

//填充bind结构数组,m_sInsertParam是这个statement关联的结构变量

memset(insertbind,0,sizeof(insertbind));

insertbind[0].buffer_type=MYSQL_TYPE_STRING;

insertbind[0].buffer_length=ID_LENGTH/*-1*/;

insertbind[0].buffer=(char*)m_stInsertParam->sessionid;

insertbind[0].is_null=0;

insertbind[0].length=0;

insertbind[1].buffer_type=MYSQL_TYPE_STRING;

insertbind[1].buffer_length=ID_LENGTH/*-1*/;

insertbind[1].buffer=(char*)m_stInsertParam->channelid;

insertbind[1].is_null=0;

insertbind[1].length=0;

insertbind[2].buffer_type=MYSQL_TYPE_TINY;

insertbind[2].buffer=(char*)&m_stInsertParam->ISPtype;

insertbind[2].is_null=0;

insertbind[2].length=0;

insertbind[3].buffer_type=MYSQL_TYPE_LONG;

insertbind[3].buffer=(char*)&m_stInsertParam->externalIP;

insertbind[3].is_null=0;

insertbind[3].length=0;

insertbind[4].buffer_type=MYSQL_TYPE_SHORT;

insertbind[4].buffer=(char*)&m_stInsertParam->externalPort;

insertbind[4].is_null=0;

insertbind[4].length=0;

insertbind[5].buffer_type=MYSQL_TYPE_LONG;

insertbind[5].buffer=(char*)&m_stInsertParam->internalIP;

insertbind[5].is_null=0;

insertbind[5].length=0;

insertbind[6].buffer_type=MYSQL_TYPE_SHORT;

insertbind[6].buffer=(char*)&m_stInsertParam->internalPort;

insertbind[6].is_null=0;

insertbind[6].is_null=0;

//绑定

if(mysql_stmt_bind_param(m_stInsertStmt,insertbind))

returnfalse;

returntrue;

}

//2.查询

boolCDBManager::InsertHostCache2(MYSQL*connecthandle,char*sessionid,char*channelid,intISPtype,

unsignedinteIP,unsignedshorteport,unsignedintiIP,unsignedshortiport)

{

//填充结构变量m_sInsertParam

strcpy(m_stInsertParam->sessionid,sessionid);

strcpy(m_stInsertParam->channelid,channelid);

m_stInsertParam->ISPtype=ISPtype;

m_stInsertParam->externalIP=eIP;

m_stInsertParam->externalPort=eport;

m_stInsertParam->internalIP=iIP;

m_stInsertParam->internalPort=iport;

//执行statement,性能瓶颈处

if(mysql_stmt_execute(m_stInsertStmt))

returnfalse;

returntrue;

}

l随机的获取记录

在某些数据库的应用中,我们并不是要获取所有的满足条件的记录,而只是要随机挑选出满足条件的记录.这种情况常见于数据业务的统计分析,从大容量数据库中获取小量的数据的场合.

有两种方法可以做到

1.常规方法,首先查询出所有满足条件的记录,然后随机的挑选出部分记录.这种方法在满足条件的记录数很多时效果不理想.

2.使用limit语法,先获取满足条件的记录条数,然后在sql查询语句中加入limit来限制只查询满足要求的一段记录.这种方法虽然要查询两次,但是在数据量大时反而比较高效.

示例代码如下:

//1.常规的方法

//性能瓶颈,10万条记录时,执行查询140ms,获取结果集500ms,其余可忽略

intCDBManager::QueryHostCache(MYSQL*connecthandle,char*channelid,intISPtype,CDBManager::CHostCacheTable*&hostcache)

{

charselectSQL[SQL_LENGTH];

memset(selectSQL,0,sizeof(selectSQL));

sprintf(selectSQL,"select*fromHostCachewhereChannelID='%s'andISPtype=%d",channelid,ISPtype);

if(mysql_real_query(connecthandle,selectSQL,strlen(selectSQL))!=0)//检索

return0;

//获取结果集

m_pResultSet=mysql_store_result(connecthandle);

if(!m_pResultSet)//获取结果集出错

return0;

intiAllNumRows=(int)(mysql_num_rows(m_pResultSet));///<所有的搜索结果数

//计算待返回的结果数

intiReturnNumRows=(iAllNumRows<=RETURN_QUERY_HOST_NUM)?iAllNumRows:RETURN_QUERY_HOST_NUM;

if(iReturnNumRows<=RETURN_QUERY_HOST_NUM)

{

//获取逐条记录

for(inti=0;i<iReturnNumRows;i++)

{

//获取逐个字段

m_Row=mysql_fetch_row(m_pResultSet);

if(m_Row[0]!=NULL)

strcpy(hostcache[i].sessionid,m_Row[0]);

if(m_Row[1]!=NULL)

strcpy(hostcache[i].channelid,m_Row[1]);

if(m_Row[2]!=NULL)

hostcache[i].ISPtype=atoi(m_Row[2]);

if(m_Row[3]!=NULL)

hostcache[i].externalIP=atoi(m_Row[3]);

if(m_Row[4]!=NULL)

hostcache[i].externalPort=atoi(m_Row[4]);

if(m_Row[5]!=NULL)

hostcache[i].internalIP=atoi(m_Row[5]);

if(m_Row[6]!=NULL)

hostcache[i].internalPort=atoi(m_Row[6]);

}

}

else

{

//随机的挑选指定条记录返回

intiRemainder=iAllNumRows%iReturnNumRows;///<余数

intiQuotient=iAllNumRows/iReturnNumRows;///<商

intiStartIndex=rand()%(iRemainder+1);///<开始下标

//获取逐条记录

for(intiSelectedIndex=0;iSelectedIndex<iReturnNumRows;iSelectedIndex++)

{

mysql_data_seek(m_pResultSet,iStartIndex+iQuotient*iSelectedIndex);

m_Row=mysql_fetch_row(m_pResultSet);

if(m_Row[0]!=NULL)

strcpy(hostcache[iSelectedIndex].sessionid,m_Row[0]);

if(m_Row[1]!=NULL)

strcpy(hostcache[iSelectedIndex].channelid,m_Row[1]);

if(m_Row[2]!=NULL)

hostcache[iSelectedIndex].ISPtype=atoi(m_Row[2]);

if(m_Row[3]!=NULL)

hostcache[iSelectedIndex].externalIP=atoi(m_Row[3]);

if(m_Row[4]!=NULL)

hostcache[iSelectedIndex].externalPort=atoi(m_Row[4]);

if(m_Row[5]!=NULL)

hostcache[iSelectedIndex].internalIP=atoi(m_Row[5]);

if(m_Row[6]!=NULL)

hostcache[iSelectedIndex].internalPort=atoi(m_Row[6]);

}

}

//释放结果集内容

mysql_free_result(m_pResultSet);

returniReturnNumRows;

}

当前1/2页12下一页阅读全文

【提高MySQL 查询效率的三个技巧第1/2页】相关文章:

MySQL中文乱码问题的解决第1/2页

MySQL十条特殊技巧

MySQL slave_net_timeout参数解决的一个集群问题案例

mysql数据库查询优化 mysql效率第1/3页

mysql的日期和时间函数大全第1/2页

101个MySQL调试和优化技巧

查询实现删除

MySQL动态创建表,数据分表的存储过程

MySQL 升级方法指南大全第1/5页

保护SQL Server 2000安全性的十个步骤

精品推荐
分类导航