MySQL高效分页解决方案集分享
时间:2024-01-26 09:29:36
一,最常见MYSQL最基本的分页方式:
select * from content order by id desc limit 0, 10
在中小数据量的情况下,这样的SQL足够用了,唯一需要注意的问题就是确保使用了索引。随着数据量的增加,页数会越来越多,查看后几页的SQL就可能类似:
select * from content order by id desc limit 10000, 10
一言以蔽之,就是越往后分页,LIMIT语句的偏移量就会越大,速度也会明显变慢。
此时,我们可以通过2种方式:
一,子查询的分页方式来提高分页效率,飘易用的SQL语句如下:
SELECT * FROM `content` WHERE id (SELECT id FROM `content` ORDER BY id desc LIMIT ".($page-1)*$pagesize.", 1) ORDER BY id desc LIMIT $pagesize
为什么会这样呢?因为子查询是在索引上完成的,而普通的查询时在数据文件上完成的,通常来说,索引文件要比数据文件小得多,所以操作起来也会更有效率。(via)通过explain SQL语句发现:子查询使用了索引!
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY content range PRIMARY PRIMARY 4 NULL 6264 Using where
2 SUBQUERY content index NULL PRIMARY 4 NULL 27085 Using index
经过飘易的实测,使用子查询的分页方式的效率比纯LIMIT提高了14-20倍!
二,JOIN分页方式
select * FROM `content` AS t1
JOIN (SELECT id FROM `content` ORDER BY id desc LIMIT ".($page-1)*$pagesize.", 1) AS t2
WHERE t1.id
经过我的测试,join分页和子查询分页的效率基本在一个等级上,消耗的时间也基本一致。explain SQL语句:
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY system NULL NULL NULL NULL 1
1 PRIMARY t1 range PRIMARY PRIMARY 4 NULL 6264 Using where
2 DERIVED content index NULL PRIMARY 4 NULL 27085 Using index
三,使用MYSQL的FOUND_ROWS()函数
Mysql FOUND_ROWS() 函数结合SQL_CALC_FOUND_ROWS在SELECT中可以得到两个结果:
1. 得到Limit的内容
2. 得到去除Limit以后所有行数
SELECT语句中经常可能用LIMIT限制返回行数。有时候可能想要知道如果没有LIMIT会返回多少行,但又不想再执行一次相同语句。那么,在SELECT查询中包含SQL_CALC_FOUND_ROWS选项,然后执行FOUND_ROWS()就可以了:
select SQL_CALC_FOUND_ROWS * FROM tbl_name WHERE id > 100 LIMIT 10;
SELECT FOUND_ROWS();
其中SQL_CALC_FOUND_ROWS 告诉Mysql将sql所处理的行数记录下来,FOUND_ROWS() 则取到了这个纪录。 虽然也是两个语句,但是只执行了一次主查询,所以效率比原来要高很多。
1. 如果在前一条语句中使用SQL_CALC_FOUND_ROWS选项,FOUND_ROWS()将返回第一条语句没有LIMIT时返回的行数。
2. 如果在前一条语句中没有使用SQL_CALC_FOUND_ROWS选项,FOUND_ROWS()将返回前一条语句实际返回的行数。
如果使用 SELECT SQL_CALC_FOUND_ROWS,MySQL必须计算所有结果集的行数。尽管这样,总比再执行一次不使用LIMIT的查询要快多了吧,因为那样结果集要返回客户端滴。(另外:应该不单是没有将结果集返回的原因,还有原因可能是比如LIKE之类比较费劲的SQL不需要再去劳累一次。)
-- 注意下面语句中的条件 LIKE
SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name WHERE Name LIKE '%string%' id > 100 LIMIT 10;
SELECT FOUND_ROWS();
-- 上面语句等价于下面语句,但性能方面应该提升非常非常的明显:
SELECT COUNT(*) FROM tbl_name WHERE Name LIKE '%string%' ;
SELECT * FROM tbl_name WHERE Name LIKE '%string%' id > 100 LIMIT 10;
![](/images/zang.png)
![](/images/jiucuo.png)
猜你喜欢
Python3 实现随机生成一组不重复数并按行写入文件
使用phpMyAdmin进行mysql数据库备份和还原的方法
![](https://img.aspxhome.com/file/uploadpic/200810/13/2008101321111543.jpg)
利用Python将彩色图像转为灰度图像的两种方法
![](https://img.aspxhome.com/file/2023/8/120268_0s.jpg)
判断字段是否被更新 新旧数据写入Audit Log表中
Python+OpenCV数字图像处理之ROI区域的提取
![](https://img.aspxhome.com/file/2023/8/81848_0s.jpg)
聊聊golang的defer的使用
Oracle时间日期操作方法小结第1/2页
js实现黑色简易的滑动门网页tab选项卡效果
![](https://img.aspxhome.com/file/2023/9/135939_0s.jpg)
利用Python实现斐波那契数列的方法实例
Python常用图像形态学操作详解
![](https://img.aspxhome.com/file/2023/7/103747_0s.png)
numpy数组广播的机制
![](https://img.aspxhome.com/file/2023/3/69543_0s.png)
python读取有密码的zip压缩文件实例
![](https://img.aspxhome.com/file/2023/6/127896_0s.jpg)
Python3.7安装keras和TensorFlow的教程图解
![](https://img.aspxhome.com/file/2023/9/81659_0s.jpg)
js为什么[]==![]是成立的吗
python脚本监控Tomcat服务器的方法
![](https://img.aspxhome.com/file/2023/2/77042_0s.png)
2行Python实现给图片加水印效果
![](https://img.aspxhome.com/file/2023/1/104981_0s.jpg)
详解CSS3中的属性选择符
python3实现磁盘空间监控
Nginx搭建HTTPS服务器和强制使用HTTPS访问的方法
![](https://img.aspxhome.com/file/2023/7/120297_0s.jpg)
Python采集大学教务系统成绩单实战示例
![](https://img.aspxhome.com/file/2023/5/72715_0s.jpg)