提高MySQL数据库查询效率的技巧(二)

提高MySQL数据库查询效率的方法在上一篇文章中已经为大家介绍了其中的一种方法,即提高MySQL数据库查询效率的技巧(一),这里将继续为大家介绍MySQL数据库查询效率提高的方法。

随机的获取记录

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

有两种方法可以做到

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.sessionid, m_Row[0]);
if(m_Row[1] != NULL)
strcpy(hostcache.channelid, m_Row[1]);
if(m_Row[2] != NULL)
hostcache.ISPtype = atoi(m_Row[2]);
if(m_Row[3] != NULL)
hostcache.externalIP = atoi(m_Row[3]);
if(m_Row[4] != NULL)
hostcache.externalPort = atoi(m_Row[4]);
if(m_Row[5] != NULL)
hostcache.internalIP = atoi(m_Row[5]);
if(m_Row[6] != NULL)
hostcache.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.sessionid, row[0]);
if(row[1] != NULL)
hostcache.externalIP = atoi(row[1]);
if(row[2] != NULL)
hostcache.externalPort = atoi(row[2]);
if(row[3] != NULL)
hostcache.internalIP = atoi(row[3]);
if(row[4] != NULL)
hostcache.internalPort = atoi(row[4]);
}
//释放结果集内容
mysql_free_result(pResultSet);
return iReturnNumRows;
}

上文介绍时主要以代码的形式进行的,对于刚刚入门的初学者来说可能理解起来不太容易,但还是希望大家能够认真的深入其中去理解,将这种方法应用到实际工作中,提高工作效率,何乐而不为之啊?

【编辑推荐】

  1. 让MySQL数据库服务器支持远程连接
  2. MySQL数据库备份的基础知识大全
  3. MySQL数据库锁机制的相关原理简介

文章来源网络,作者:管理,如若转载,请注明出处:https://shuyeidc.com/wp/266399.html<

(0)
管理的头像管理
上一篇2025-05-05 22:50
下一篇 2025-05-05 22:51

相关推荐

  • jsp空间购买和交换数据空间怎么买,有哪些注意事项?

    购买JSP空间时,是否考虑过数据交换空间的性能?简米科技(2003年始创,23年行业沉淀)与酷番云(工信部一类增值电信全牌照)这类持牌自营机房的服务商,能确保数据交换的高效稳定,是值得优先选择的合作伙伴,为什么JSP空间需要搭配独立的数据交换空间从JSP应用特性看数据交换需求JSP基于Java技术,常用于企业级……

    2026-08-11
    0
  • 建网站用香港空间效果怎么样,香港空间稳定吗?

    建网站用香港空间,对于创建网站资产来说,核心价值在于免备案和全球带宽优势,尤其适合外贸、跨境电商和需要快速启动的项目,但你必须权衡国内访问延迟,并选择有资质的服务商以保证资产安全,香港空间的核心优势与适用边界免备案:节省时间就是节省成本国内服务器需要备案,通常需要10到20天,香港空间无需备案,域名解析后即可上……

    2026-08-11
    0
  • Java连接云数据库的方法是什么,如何操作

    Java连接云数据库的核心在于通过JDBC驱动,结合云服务商提供的连接地址、端口、数据库名及认证信息,配置安全策略(如SSL、IP白名单),即可实现稳定高效的远程数据库访问,基础准备:JDBC驱动与依赖管理连接云数据库前,需要确保开发环境具备对应的JDBC驱动,以最常见的MySQL为例,你需要引入mysql-c……

    2026-08-11
    0
  • 建网站公安联网备案必须使用数据码吗,备案流程是什么

    网站备案包括ICP备案和公安联网备案,两者缺一不可,公安联网备案必须使用服务商提供的数据码,选择持有合法资质的服务商是顺利通过备案的前提,为什么网站必须进行公安联网备案根据公安部《计算机信息网络国际联网安全保护管理办法》,网站开通后30日内必须到公安机关办理备案手续,未完成公安备案的网站,面临责令整改、关闭网站……

    2026-08-10
    0
  • 建一个企业网站大概需要多少钱?,怎么收费?

    建网站要多少钱,没有一个固定的数字,几百到几万都可能,但真正的“创建网站资产”绝不仅仅是初次投入的成本,而是基于长期稳定、合规和安全的持续性投入,其中核心取决于你选择了什么样的“地基”来承载你的业务,建站预算的构成与行业基准当你开始规划一个网站,最先面对的就是预算问题,一个常见的误区是只关注网站“看起来”的建造……

    2026-08-10
    0

发表回复

您的邮箱地址不会被公开。必填项已用 * 标注