关闭

MySQL 高效分页

标签: mysql分页
310人阅读 评论(0) 收藏 举报

很久以前的一次面试中,被面试官问到这个问题,由于平时用到的分页方法不多,只从索引、分表、使用子查询精准定位偏移以外,没有使用到其它方法。

后来在看其它博客看到了一些不同的方案,也一直没有整理。今天有时间,整理出来,分享给大家。

一,最常见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 in (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 on t1.id = t2.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;

参考博客:

http://blog.hexu.org/archives/1328.shtml

http://hi.baidu.com/thinkinginlamp/blog/item/17476d22d66876a14623e81d.html

http://www.piaoyi.org/php/MySQL-SUBQUERY-index.html

0
0
查看评论

Mysql分页查询高效方案

mysql分页高效方案
  • bestcleaner
  • bestcleaner
  • 2016-11-01 10:24
  • 4360

【基础知识思考整理 】Mysql高效率的分页查询

在工程实践中,数据库表中的数据量一般不超过 100W行。当我们想要查询数据表中满足条件的第 n个100 行数据的时候,怎样的查询方法才能保证较高的性能呢?首先想到的,一般分页都是用 “limit 起始, 行数” 这样的方式。 上面的含义是:即使我们只要取得从第 2个开始的3 行数据,也要扫描前...
  • aganlengzi
  • aganlengzi
  • 2016-10-17 09:34
  • 940

MySQL详解(19)----------海量数据分页查询优化

分页的具体讲解讲解请看http://blog.csdn.net/u011225629/article/details/46775947 查看代码打印1 SELECT * FROM table ORDER BY id LIMIT 1000,10; 以上SQL语句在原理上和在实际操作中是不会存在什么...
  • u011225629
  • u011225629
  • 2015-07-06 16:19
  • 7305

asp.net (c#) MySQL 大数据快速分页

aspx页:<asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="True" ...
  • wslyy99
  • wslyy99
  • 2009-10-16 10:07
  • 1910

MySQL联合查询分页

有两个表table_A, table_B:pro: id pro_name creator_id create_time 1 pro1 101 2017-5-1 2 pro2 103 2017-3-1 3 pro3 103 2017-2-...
  • Joker_Fei
  • Joker_Fei
  • 2017-05-29 14:59
  • 736

ASP超高效分页算法

'每页的记录数 dim pagesize pagesize= "30" '读出总记录数,总页数,飘易注 Dim TotalRecords,TotalPages SQLstr="Select count(id) As RecordSum Fro...
  • tianpeiwen
  • tianpeiwen
  • 2012-12-14 10:17
  • 480

mysql大数据量使用limit分页,随着页码的增大,查询效率越低下。

转载地址:http://www.cnblogs.com/lpfuture/p/5772055.html 测试实验 1.   直接用limit start, count分页语句, 也是我程序中用的方法: select * from&...
  • lengyue1084
  • lengyue1084
  • 2017-03-08 10:50
  • 3240

php高效获取数据分页

mysql.php 获取数据库中的记录,完全个人经验总结,仅供参考! /** *PHP+MYSQL数据库基本功能 *http://blog.csdn.net/yown */ ############################################ #获取序列ID #...
  • SJian123
  • SJian123
  • 2014-06-25 18:03
  • 1402

MongoDB 性能优化之分页查询

最常见的分页采用的是skip+limit这种组合方式,这种方式对付小数据倒也可以,但是对付上几百上千万的大数据,只能力不从心。通过如下思路改善,可以大大提高查询速度:条件查询+排序+限制返回记录。边查询,边排序,排序之后,抽取第一次分页中的最后一条记录,作为第二次分页的条件,进行条件查询,以此类推....
  • tianwei7518
  • tianwei7518
  • 2015-03-19 21:39
  • 9078

asp高效率分页代码

 Option Explicit Response.Flush Dim BeginTime,EndTime BeginTime=Timer Dim conn,SQLstr,Rs,DefRecordNum,CursorBegin,CursorEnd,CurPageNum,hav DefRec...
  • chinaPhoneLab
  • chinaPhoneLab
  • 2007-08-03 11:06
  • 2369
    个人资料
    • 访问:32553次
    • 积分:518
    • 等级:
    • 排名:千里之外
    • 原创:17篇
    • 转载:8篇
    • 译文:0篇
    • 评论:4条
    最新评论