当前位置: 首页 > 图文教程 > 数据库 > MYSQL > 提高MySQL 查询效率的三个技巧(2)

MYSQL
Mysql中mysqldump命令使用详解
常见mysql错误代码详细解析
设置 MySql 数据同步
MySQL集群配置
ASP连接MySQL数据库的方法
linux操作系统下建立mysql镜像数据库
加大MySql的最大连接数
使用"函数递归"实现基于php和MySQL的动态树型菜单
基于MySQL的高性能数据库应用开发
在同一台机器上运行多个MySQL服务器
从MySQL到ORACLE程序迁移的注意事项
安全专家讲解Mysql故障详细的诊断过程
Mysql中日期和时间函数应用不用求人
你可能不知道 Mysql的常用命令收集
您可能不知道 MySQL表最大能达到多少
mysql5中遭遇的字符集问题及其解决方案
教你轻松的掌握 MYSQL连接字符集和校对
快速的掌握可以运行MySQL的操作系统
在服务器上安装使用 MySQL 的注意事项
简简单单掌握对MySQL无效数据的约束

MYSQL 中的 提高MySQL 查询效率的三个技巧(2)


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-08-14   浏览: 145 ::
收藏到网摘: n/a

二、随机的获取记录

在某些数据库的应用中, 我们并不是要获取所有的满足条件的记录,而只是要随机挑选出满足条件的记录. 这种情况常见于数据业务的统计分析,从大容量数据库中获取小量的数据的场合.
      有两种方法可以做到
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));
       sprintf(selectSQL,"select * from HostCache where ChannelID = '%s' and ISPtype = %d", channelid, ISPtype);
       if(mysql_real_query(connecthandle, selectSQL, strlen(selectSQL)) != 0)   //检索
              return 0;
       //获取结果集
       m_pResultSet = mysql_store_result(connecthandle);
       if(!m_pResultSet)   //获取结果集出错
              return 0;
       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)
                            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
       {
              //随机的挑选指定条记录返回
              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);
                            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);
       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;
       char selectSQL[SQL_LENGTH];
       memset(selectSQL, 0, sizeof(selectSQL));
 
       sprintf(selectSQL,"select count(*) from HostCache where ChannelID = '%s' and ISPtype = %d", channelid, ISPtype);
       if(mysql_real_query(connecthandle, selectSQL, strlen(selectSQL)) != 0)   //检索
              return 0;
       pResultSet = mysql_store_result(connecthandle);
       if(!pResultSet)      
              return 0;
       row = mysql_fetch_row(pResultSet);
       int iAllNumRows = atoi(row[0]);
       mysql_free_result(pResultSet);
       //计算待取记录的上下范围
       int iLimitLower = (iAllNumRows <= RETURN_QUERY_HOST_NUM)?
              0:(rand()%(iAllNumRows - RETURN_QUERY_HOST_NUM));
       int iLimitUpper = (iAllNumRows <= RETURN_QUERY_HOST_NUM)?
              iAllNumRows:(iLimitLower + RETURN_QUERY_HOST_NUM);
       //计算待返回的结果数
       int iReturnNumRows = (iAllNumRows <= RETURN_QUERY_HOST_NUM)?
               iAllNumRows:RETURN_QUERY_HOST_NUM;
      
       //使用limit作查询
       sprintf(selectSQL,"select SessionID, ExternalIP, ExternalPort, InternalIP, InternalPort "
              "from HostCache where ChannelID = '%s' and ISPtype = %d limit %d, %d"
              , channelid, ISPtype, iLimitLower, iLimitUpper);
       if(mysql_real_query(connecthandle, selectSQL, strlen(selectSQL)) != 0)   //检索
              return 0;
       pResultSet = mysql_store_result(connecthandle);
       if(!pResultSet)
              return 0;
       //获取逐条记录
       for(int i = 0; i<iReturnNumRows; i++)
       {
              //获取逐个字段
              row = mysql_fetch_row(pResultSet);
              if(row[0] != NULL)
                     strcpy(hostcache[i].sessionid, row[0]);
              if(row[1] != NULL)
                     hostcache[i].externalIP   = atoi(row[1]);
              if(row[2] != NULL)
                     hostcache[i].externalPort = atoi(row[2]);
              if(row[3] != NULL)
                     hostcache[i].internalIP   = atoi(row[3]);
              if(row[4] != NULL)
                     hostcache[i].internalPort = atoi(row[4]);            
       }
       //释放结果集内容
       mysql_free_result(pResultSet);
       return iReturnNumRows;
}