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

MYSQL
Windows 2003搭建Apache PHP MySQL环境经验分享
PHP环境配置IIS5.0+PHP5.23+MYSQL5+phpMyAdmin
详解用phpmyadmin建立MYSQL数据库的过程
几条常见的数据库分页 SQL 语句
将MySQL数据导入到Sql Server中
解决MySQL数据库中文模糊检索问题
MySQL索引分析和优化
提高MySQL查询效率的三个有效的尝试
MySQL查询不含周末的五天前的日期
连接MySQL数据库失败频繁的原因分析
SQL Server和MySQL的安全性分析
Linux搭建Discuz论坛的方法
如何保护MySQL中的重要数据
怎样把你的 MySQL 完全中文化
FreeBSD 6.2快速架设网站服务器教程
Oracle限制返回结果集的大小
MySQL中与浮点比较有关问题的解决
distinct在mysql中查询多条不重复记录值的解决办法
全面提升Linux服务器的安全
不能通过mysql.sock连接MySQL问题的方法

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


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-08-14   浏览: 147 ::
收藏到网摘: 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;
}