时间:2021-07-01 10:21:17 帮助过:31人阅读
很多程序朋友在写分页是特别是mysql有了limit n,m;这样的写法,分页从此简单了,但方不知道这种分页几万数据没有问题,但在百万千万级时就无法使用了,今天我们来介绍这两种分页的优化方法。
PHP写功能时,只要用的还是MySQL,基本都是两步走
1、取得总数,算页数。SQL语句自然是
代码如下 | |
SELECT count(*) FROM tablename; |
2、根据指定的页码号,取得相应的数据。对应的SQL语句,在网上随便查,都是一样的:
SELECT f1,f2 FROM table LIMIT offset,length
实例分页类
代码如下 | |
var $start_index; //所要显示记录的首行序号 var $total_pages; //总页数 var $arr_page_query; //数组,包含分页显示需要传递的参数 var $first; //方法
} /********************************************* /********************************************* /********************************************* //查询数据,数据库链接等信息应在类调用的外部实现 //利用LIMIT关键字获取本页所要显示的记录 $result=mysql_query($psql) or die(mysql_error()); //将查询结果放在result数组中
$this->first=1; /********************************************* "; ";
echo ""; echo " } /********************************************* "; ";
echo ""; echo " } } 调用:
include_once("../config_jj/sys_conf.inc"); $smarty = new Smarty_Jsnh();
$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); } ?> if ($pageSupport->current_records > 0) //如果数据不为空,则组装数据 $news_arr[$i] = array('news' => array('id' => $id,'title' => $title)); } //关闭数据库 $pageinfo_arr = array( $smarty->assign('results', $news_arr); ?> {foreach item=o from=$results}
{/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(); | ||||||
” target=”_blank”> |