Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
586 views
in Technique[技术] by (71.8m points)

MySQL分页查询,是用LIMIT m,n,还是先查出所有ID再在前端分页?

用传统的LIMIT m, n做分页查询需要这么几步:

  1. SELECT COUNT(*) FROM table WHERE condition ORDER BY ...查到总数并算出有多少页;

  2. SELECT columns FROM table WHERE condition ORDER BY ... LIMIT 0, 100显示第一页(假设每页有100行),如果用SQL_CALC_FOUND_ROWS这个参数的话,可以跟前一条合并成一条SQL;

  3. 点“下一页”时,用SELECT columns FROM table WHERE condition ORDER BY ... LIMIT 100, 100查;

  4. ...

这样做往往花费很大,因为WHERE condition有可能是全表扫描。如果MySQL没开缓存的话,每翻一页可能非常慢。

因此我就用一种新的办法:

  1. SELECT id FROM table WHERE condition ORDER BY ...得到所有相符的ID,如果数据量太大(比如表中有1,000,000行),我们就限制一下行数(比如限制最多查10,000,就用LIMIT 10000),于是这些ID就通过动态页面或Ajax(以JS代码或JSON的形式)被传到了前端;

  2. 前端JS选取前100个ID作为第一页,发送一个带这100个ID的查询请求,后端其实处理SELECT columns FROM table WHERE id IN (id_0, id_1, ..., id_99)这么一个查询;

  3. 点“下一页”时,查询是SELECT columns FROM table WHERE id IN (id_100, id_101, ..., id_199)

  4. ...

这种方法只需要做一次条件查询(慢),列表数据其实都是主键查询(快)。

我在一个业余项目中用了这个办法,详见:(http://) www.chess-wizard.com/base/ (第一页数据被写在JSP页面里,有利于SEO).

我要求团队成员都用这种方式来处理分页,他们却并不认同 :-(

难道LIMIT m, n是分页查询的标准做法唯一途径吗?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

一种id>$id limit $limit;传递参数$offset,$limit=100;

第一页:$offset = 0

select id ,name from table order by id limit $limit;

第二页:$offset为第一页返回的id

select id ,name from table where id>$offset order by id limit $limit;


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...