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

数据库 MySQL
MySQL数据库查询是数据库应用中一个比较重要的功能,MySQL数据库查询的快慢就直接影响着数据库操作的效率,拿么怎样来提高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数据库锁机制的相关原理简介
责任编辑:迎迎 来源: 赛迪网
相关推荐

2011-04-02 09:33:13

MySQL数据库查询效率

2011-04-02 09:23:19

MySQL数据库查询效率

2010-04-07 17:45:22

Oracle位图索引

2010-10-27 14:15:44

Oracle数据库效率

2010-08-27 13:27:50

DB2备份恢复

2023-10-09 18:13:14

MySQL数据库查询

2011-08-03 18:01:54

MySQL数据库提高查询速度

2011-04-11 16:50:13

Oracle数据库索引

2009-05-15 10:11:55

数据库查询查询性能分页浏览

2018-01-10 09:33:18

数据库SQL查询优化Java Web

2018-05-24 08:47:15

数据存储技巧

2018-10-24 15:55:19

MySQL数据库技巧

2012-07-06 09:00:34

MySQL

2011-03-17 14:48:49

高级扫描数据库查询

2009-06-30 15:54:00

数据库访问JSP

2010-05-27 17:16:20

MySQL数据库

2010-11-22 13:23:52

MySQL数据库优化

2010-05-31 14:50:49

MySQL数据库性能

2009-07-06 21:20:34

SQL Server数

2020-11-26 10:29:01

Redis
点赞
收藏

51CTO技术栈公众号