当前位置:首页 > 技术与方案 > 数据库技术相关

提高MySQL查询效率的三个技巧

(2012-09-25 15:06:49)

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

 

使用statement进行绑定查询

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

使用方法是:

绑定, 创建一个MYSQL_STMT变量,与对应的查询字符串绑定,字符串中的问号代表要传入的变量,每个问号都必须指定一个变量. 查询, 输入每个指定的变量, 传入MYSQL_STMT变量用可用的连接句柄执行.

代码如下:

//1.绑定 ool CDBManager::BindInsertStmt(MYSQL * connecthandle) 作插入操作的绑定 MYSQL_BIND insertbind[FEILD_NUM]; if(m_stInsertParam == NULL) m_stInsertParam = new CHostCacheTable; m_stInsertStmt = mysql_stmt_init(connecthandle); 构建绑定字符串 char insertSQL[SQL_LENGTH]; trcpy(insertSQL, "insert into HostCache(SessionID, ChannelID, ISPType, " "ExternalIP, ExternalPort, InternalIP, InternalPort) " mysql_stmt_prepare(m_stInsertStmt, insertSQL, strlen(insertSQL)); int param_count= mysql_stmt_param_count(m_stInsertStmt); if(param_count != FEILD_NUM) 填充bind结构数组, m_sInsertParam是这个statement关联的结构变量 insertbind[0].buffer_type = MYSQL_TYPE_STRING; insertbind[0].buffer_length = ID_LENGTH /* -1 */; insertbind[0].buffer = (char *)m_stInsertParam- sessionid; insertbind[1].buffer = (char *)m_stInsertParam- channelid; insertbind[2].buffer_type = MYSQL_TYPE_TINY; insertbind[2].buffer = (char *) m_stInsertParam- ISPtype; insertbind[3].buffer_type = MYSQL_TYPE_LONG; insertbind[3].buffer = (char *) m_stInsertParam- externalIP; insertbind[4].buffer_type = MYSQL_TYPE_SHORT; insertbind[4].buffer = (char *) m_stInsertParam- externalPort; insertbind[5].buffer = (char *) m_stInsertParam- internalIP; insertbind[6].buffer = (char *) m_stInsertParam- internalPort; 绑定 if (mysql_stmt_bind_param(m_stInsertStmt, insertbind)) 随机的获取记录

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

有两种方法可以做到

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

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

示例代码如下:

//1.常规的方法 //性能瓶颈,10万条记录时,执行查询140ms, 获取结果集500ms,其余可忽略 int CDBManager::QueryHostCache(MYSQL* connecthandle, char * channelid, int ISPtype, CDBManager::CHostCacheTable * hostcache) char selectSQL[SQL_LENGTH]; memset(selectSQL, 0, sizeof(selectSQL)); rintf(selectSQL,"select * from HostCache where ChannelID = '%s' and ISPtype = %d", channelid, ISPtype); if(mysql_real_query(connecthandle, selectSQL, strlen(selectSQL)) != 0) // 检索获取结果集 m_pResultSet = mysql_store_result(connecthandle); 获取结果集出错 int iAllNumRows = (int)(mysql_num_rows(m_pResultSet)); /// 所有的搜索结果数计算待返回的结果数 int iReturnNumRows = (iAllNumRows = RETURN_QUERY_HOST_NUM)? iAllNumRows:RETURN_QUERY_HOST_NUM; if(iReturnNumRows = RETURN_QUERY_HOST_NUM) 获取逐条记录 for(int i = 0; i iReturnNumRows; i++) 获取逐个字段 m_Row = mysql_fetch_row(m_pResultSet); if(m_Row[0] != NULL) if(m_Row[1] != NULL) trcpy(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]); 随机的挑选指定条记录返回 int iRemainder = iAllNumRows%iReturnNumRows; /// 余数 int iQuotient = iAllNumRows/iReturnNumRows; /// int iStartIndex = rand()%(iRemainder + 1); /// 开始下标 for(int iSelectedIndex = 0; iSelectedIndex iReturnNumRows; iSelectedIndex++) mysql_data_seek(m_pResultSet, iStartIndex + iQuotient * iSelectedIndex); trcpy(hostcache[iSelectedIndex].sessionid, m_Row[0]); trcpy(hostcache[iSelectedIndex].channelid, m_Row[1]); hostcache[iSelectedIndex].ISPtype = atoi(m_Row[2]); hostcache[iSelectedIndex].externalIP = atoi(m_Row[3]); hostcache[iSelectedIndex].externalPort = atoi(m_Row[4]); hostcache[iSelectedIndex].internalIP = atoi(m_Row[5]); hostcache[iSelectedIndex].internalPort = atoi(m_Row[6]); 释放结果集内容 return iReturnNumRows; //2.使用limit版 int CDBManager::QueryHostCache(MYSQL * connecthandle, char * channelid, unsigned int myexternalip, int ISPtype, CHostCacheTable * hostcache) 首先获取满足结果的记录条数,再使用limit随机选择指定条记录返回 MYSQL_ROW row; MYSQL_RES * pResultSet; rintf(selectSQL,"select count(*) from HostCache where ChannelID = '%s' and ISPtype = %d", channelid, ISPtype);

 

更多
关闭窗口 打印 
网站首页    -    联系我们    -   收藏本站    -    网站地图                                                               客户服务热线:0571-85023000
本网站所有网页信息已申请知识产权和著作权保护,版权归四海光纤公司所有,未经授权禁止任何人复制或镜像,违者必究。
公司主营:杭州光纤光缆视频会议系统,是专业的通信网络工程、视频会议系统建设专家

中华人民共和国备案号:浙ICP备10018243号