热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

mysql百万条数据分页优化

很多程序朋友在写分页是特别是mysql有了limitn,m;这样的写法,分页从此简单了,但方不知道这种分页几万数据没有问题,但在百万千万级时就无法使用了,今天我们来介绍这两种分页的优化方法。

很多程序朋友在写分页是特别是mysql有了limit n,m;这样的写法,分页从此简单了,但方不知道这种分页几万数据没有问题,但在百万千万级时就无法使用了,今天我们来介绍这两种分页的优化方法。

PHP写功能时,只要用的还是MySQL,基本都是两步走

1、取得总数,算页数。SQL语句自然是

代码如下
SELECT count(*) FROM tablename;

2、根据指定的页码号,取得相应的数据。对应的SQL语句,在网上随便查,都是一样的:

SELECT f1,f2 FROM table LIMIT offset,length

实例分页类

代码如下

/*********************************************
类名: PageSupport
功能:分页显示MySQL中的数据
***********************************************/
class PageSupport{
//属性
var $sql; //所要显示数据的SQL查询语句
var $page_size; //每页显示最多行数

var $start_index; //所要显示记录的首行序号
var $total_records; //记录总数
var $current_records; //本页读取的记录数
var $result; //读出的结果

var $total_pages; //总页数
var $current_page; //当前页数
var $display_count = 30; //显示的前几页和后几页数

var $arr_page_query; //数组,包含分页显示需要传递的参数

var $first;
var $prev;
var $next;
var $last;

//方法
/*********************************************
构造函数:__construct()
输入参数:
$ppage_size:每页显示最多行数
***********************************************/
function PageSupport($ppage_size)
{
$this->page_size=$ppage_size;
$this->start_index=0;
}


/*********************************************
构造函数:__destruct()
输入参数:
***********************************************/
function __destruct()
{

}

/*********************************************
get函数:__get()
***********************************************/
function __get($property_name)
{
if(isset($this->$property_name))
{
return($this->$property_name);
}
else
{
return(NULL);
}
}

/*********************************************
set函数:__set()
***********************************************/
function __set($property_name, $value)
{
$this->$property_name = $value;
}

/*********************************************
函数名:read_data
功能: 根据SQL查询语句从表中读取相应的记录
返回值:属性二维数组result[记录号][字段名]
***********************************************/
function read_data()
{
$ql=$this->sql;

//查询数据,数据库链接等信息应在类调用的外部实现
$result=_query($psql) or die(mysql_error());
$this->total_records=mysql_num_rows($result);

//利用LIMIT关键字获取本页所要显示的记录
if($this->total_records>0)
{
$this->start_index = ($this->current_page-1)*$this->page_size;
$psql=$psql. " LIMIT ".$this->start_index." , ".$this->page_size;

$result=mysql_query($psql) or die(mysql_error());
$this->current_records=mysql_num_rows($result);

//将查询结果放在result数组中
$i=0;
while($row=mysql_fetch_Array($result))
{
$this->result[$i]=$row;
$i++;
}
}


//获取总页数、当前页信息
$this->total_pages=ceil($this->total_records/$this->page_size);

$this->first=1;
$this->prev=$this->current_page-1;
$this->next=$this->current_page+1;
$this->last=$this->total_pages;
}

/*********************************************
函数名:standard_navigate()
功能: 显示首页、下页、上页、未页
***********************************************/
function standard_navigate()
{
echo "

";
echo "";

echo "第".$this->current_page."页/共".$this->total_pages."页";
echo " ";

echo "跳到页";
echo "";


//生成导航链接
if ($this->current_page > 1) {
echo "首页|";
echo "上一页|";
}

if( $this->current_page <$this->total_pages) {
echo "下一页|";
echo "末页";
}

echo "";
echo "

";

}

/*********************************************
函数名:full_navigate()
功能: 显示首页、下页、上页、未页
生成导航链接 如1 2 3 ... 10 11
***********************************************/
function full_navigate()
{
echo "

";
echo "";

echo "第".$this->current_page."页/共".$this->total_pages."页";
echo " ";

echo "跳到页";
echo "";

//生成导航链接 如1 2 3 ... 10 11
$front_start = 1;
if($this->current_page > $this->display_count){
$front_start = $this->current_page - $this->display_count;
}
for($i=$front_start;$i<$this->current_page;$i++){
echo "[".$i ."] ";
}

echo "[".$this->current_page."]";

$displayCount = $this->display_count;
if($this->total_pages > $displayCount&&($this->current_page+$displayCount)<$this->total_pages){
$displayCount = $this->current_page+$displayCount;
}else{
$displayCount = $this->total_pages;
}

for($i=$this->current_page+1;$i<=$displayCount;$i++){
echo "[".$i ."] ";
}

//生成导航链接
if ($this->current_page > 1) {
echo "首页|";
echo "上一页|";
}

if( $this->current_page <$this->total_pages) {
echo "下一页|";
echo "末页";
}

echo "";
echo "

";

}

}
?>

调用:

include_once("../config_jj/sys_conf.inc");
include_once("../PageSupportClass.php");//分页类
include_once('../Smarty_JsnhClass.php');

$smarty = new Smarty_Jsnh();
include_once("../include/Smarty_changed_dir.php");
$smarty->assign('title', "Smarty新闻分页测试");

$pageSupport = new PageSupport($PAGE_SIZE); //实例化PageSupport对象

$current_page=$_GET["current_page"];//分页当前页数

if (isset($current_page)) {

$pageSupport->__set("current_page",$current_page);

} else {

$pageSupport->__set("current_page",1);

}

?>
$pageSupport->__set("sql"," * from news ");
$pageSupport->read_data();//读数据

if ($pageSupport->current_records > 0) //如果数据不为空,则组装数据
{
for ($i=0; $i<$pageSupport->current_records; $i++)
{
$title = $pageSupport->result[$i]["title"];
$id = $pageSupport->result[$i]["id"];

$news_arr[$i] = array('news' => array('id' => $id,'title' => $title));

}
}

//关闭数据库
mysql_close($db);

$pageinfo_arr = array(
'total_records' => $pageSupport->total_records,
'current_page' => $pageSupport->current_page,
'total_pages' => $pageSupport->total_pages,
'first' => $pageSupport->first,
'prev' => $pageSupport->prev,
'next' => $pageSupport->next,
'last' => $pageSupport->last
);

$smarty->assign('results', $news_arr);
$smarty->assign('pageSupport', $pageinfo_arr);
$smarty->display('news/list.tpl');

?>
模板list.tpl
{* I am a Smarty comment, I don't exist in the compiled output *}
{*
{$pageSupport.total_records}

{$pageSupport.current_page}

{$pageSupport.total_pages}

{$pageSupport.first}

{$pageSupport.prev}

{$pageSupport.next}

{$pageSupport.last}

*}





{foreach item=o from=$results}
{$o.news.id} {$o.news.title}


{foreachelse}
没有您要查看的数据!
{/foreach}



{if ( $pageSupport.total_records > 0 )}


共{$pageSupport.total_records}记录
第{$pageSupport.current_page}页/共{$pageSupport.total_pages}页
{if ( $pageSupport.current_page > 1 )}
首页
上一页
{/if}

{if ( $pageSupport.current_page <$pageSupport.total_pages )}
下一页
末页
{/if}

跳到

{/if}




语法,不解释了,数据量小的时候,这么写,没事。

如果数据量大呢?不是一般大,上百万呢。

试着运行一下:

代码如下

SELECT id FROM users LIMIT 1000000,10

在我的电脑上,第一次运行,显示如下:

10 rows in set (9.38 sec)

之后再运行,显示如下:

10 rows in set (0.38 sec)

这不奇怪。MySQL对已经运行的SQL语句有缓冲,可以很快把之前的数据拿出来。

无论如何,第一次的9秒多,我实在不能接受。

换个写法:

代码如下

SELECT id FROM users WHERE id>1000000 LIMIT 10;

显示:10 rows in set (0.00 sec)

事实上,用phpMyAdmin去看,“显示行 0 - 9 (10 总计, 查询花费 0.0011 秒)”,之后再运行,基本都在0.0003秒左右。

百万级优化

.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。

  2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:

代码如下

  select id from t where num is null

  可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:

代码如下

  select id from t where num=0

  3.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。

  4.应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如:

代码如下

  select id from t where num=10 or num=20

  可以这样查询:

代码如下

  select id from t where num=10

  union all

select id from t where num=20

  5.in 和 not in 也要慎用,否则会导致全表扫描,如:

 

代码如下
 select id from t where num in(1,2,3)

  对于连续的数值,能用 between 就不要用 in 了:

  

代码如下
select id from t where num between 1 and 3

  6.下面的查询也将导致全表扫描:

 

代码如下
 select id from t where name like '%abc%'

分类函数











代码如下

$db=dblink();
$db->pagesize=20;
$sql=”select id from collect where vtype=$vtype”;
$db->execute($sql);
$strpage=$db->strpage(); //将分页字符串保存在临时变量,方便输出
while($rs=$db->fetch_array()){
$strid.=$rs['id'].’,';
}
$strid=substr($strid,0,strlen($strid)-1); //构造出id字符串
$db->pagesize=0; //很关键,在不注销类的情况下,将分页清空,这样只需要用一次数据库连接,不需要再开;
$db->execute(“select id,title,url,sTime,gTime,vtype,tag from collect where id in ($strid)”);
fetch_array()): ?>

           ” target=”_blank”>  

echo $strpage;


推荐阅读
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 如何实现织梦DedeCms全站伪静态
    本文介绍了如何通过修改织梦DedeCms源代码来实现全站伪静态,以提高管理和SEO效果。全站伪静态可以避免重复URL的问题,同时通过使用mod_rewrite伪静态模块和.htaccess正则表达式,可以更好地适应搜索引擎的需求。文章还提到了一些相关的技术和工具,如Ubuntu、qt编程、tomcat端口、爬虫、php request根目录等。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • Oracle Database 10g许可授予信息及高级功能详解
    本文介绍了Oracle Database 10g许可授予信息及其中的高级功能,包括数据库优化数据包、SQL访问指导、SQL优化指导、SQL优化集和重组对象。同时提供了详细说明,指导用户在Oracle Database 10g中如何使用这些功能。 ... [详细]
  • 本文介绍了在SpringBoot中集成thymeleaf前端模版的配置步骤,包括在application.properties配置文件中添加thymeleaf的配置信息,引入thymeleaf的jar包,以及创建PageController并添加index方法。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • 本文详细介绍了SQL日志收缩的方法,包括截断日志和删除不需要的旧日志记录。通过备份日志和使用DBCC SHRINKFILE命令可以实现日志的收缩。同时,还介绍了截断日志的原理和注意事项,包括不能截断事务日志的活动部分和MinLSN的确定方法。通过本文的方法,可以有效减小逻辑日志的大小,提高数据库的性能。 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • 推荐一个ASP的内容管理框架(ASP Nuke)的优势和适用场景
    本文推荐了一个ASP的内容管理框架ASP Nuke,并介绍了其主要功能和特点。ASP Nuke支持文章新闻管理、投票、论坛等主要内容,并可以自定义模块。最新版本为0.8,虽然目前仍处于Alpha状态,但作者表示会继续更新完善。文章还分析了使用ASP的原因,包括ASP相对较小、易于部署和较简单等优势,适用于建立门户、网站的组织和小公司等场景。 ... [详细]
  • GetWindowLong函数
    今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 本文讨论了Alink回归预测的不完善问题,指出目前主要针对Python做案例,对其他语言支持不足。同时介绍了pom.xml文件的基本结构和使用方法,以及Maven的相关知识。最后,对Alink回归预测的未来发展提出了期待。 ... [详细]
author-avatar
叶葳蕤1095190287
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有