合理使用MySQL的Limit进行分页
今天看一个水友说他的MySQL现在变的很慢。问什么情况时。说单表超过2个G的一个MyISAM。真垃圾的回答方式。
简单答复:换一个强劲的服务器。换服务器很管用的:)
………
最终让取到慢查询:
以下是代码片段: SELECT * FROM pw_gbook WHERE uid=’N’ ORDER BY postdate DESC LIMIT N,N; |
如:
以下是代码片段: SELECT * FROM pw_gbook WHERE uid=’48’ ORDER BY postdate DESC LIMIT 1275480,20; |
看到这个语句我都吐血了(BT的PHPWIND分页啊,这个语句是PHP初学者写出来的还正常,但PHPWIND那么成熟的社区了还有这样的问题)。
我这里简单说一下LIMIT的原理。这里以LIMIT N,M为基础:LIMIT首先要找查N+M行,然后从N行处,取M行。那么这样的SQL对一次查询1275500一个操作应该是一个昂贵的开销。对于LIMIT这类的优化,第一个目标就是让N变的尽可能的小或是不用。
怎么才能使这个N尽可能小呢。我们能做的其实就是用相对的值,给分页一个提示。如现在我们看的是第5页,看完看想看第6页,第6页同样显示是20条记录。我们就可以想到,以这个例子为准:我们可以肯定的是第6页的日值应小于第5页的,如果第5页的最小日值为:2009-11-4,那我们就可以用:
以下是代码片段: SELECT * FROM pw_gbook WHERE uid=’48’ and postdate<’2009-11-1’ ORDER BY postdate DESC LIMIT 20; |
以下是代码片段: SELECT * FROM pw_gbook WHERE uid=’48’ and postdate>’2009-11-3’ ORDER BY postdate DESC LIMIT 20; |
再说一下这种业务的SQL怎么实现:对于分页的展示可以用多用类型。这里说三种常用的类型:
第一种:显示“上一页” “下一页”这种类型
这种方式相对简单也就出现了我们看到那种SQL不思考的写法。合理的做法:
第一页:
以下是代码片段: SELECT * FROM pw_gbook WHERE uid=’48’ ORDER BY postdate DESC LIMIT 20; |
第二页:根据第一页的postdate进行查询如:
以下是代码片段: SELECT * FROM pw_gbook WHERE uid=’48’ and postdate<’2009-11-3’ ORDER BY postdate DESC LIMIT 20; |
第二种:显示 “ 1,2,3,4,5…”
第一页: 还是以第一页的方式实现:
以下是代码片段: SELECT * FROM pw_gbook WHERE uid=’48’ ORDER BY postdate DESC LIMIT 20; |
第二页:和原来一样。如果跳页,如从第二页跳到第5页,这里有一个第二页的最小日期为:2009-11-3(假设值,可以由第二页的程序查询得到),第二到第5,差2页,每页20条记录,那么就可以用:
以下是代码片段: SELECT * FROM pw_gbook WHERE uid=’48’ and postdate<’2009-11-3’ ORDER BY postdate DESC LIMIT 40,20; |
第三种:显示 “1,2,3,4,5,…. 末页” 或是 “首页,<<100,101,102,103 >>末页”
这里有一个特殊的一地方:
别的页面的跳转的上面一样。这里就加一个末页,这里又分两种情况,如果知道最后一页是多少页,也就知道了前一页的最小日期(分页提示值),这样就可以用上面的方法查看最后一页的内容(会出现不足20条的现象),另一种,我就不知道最后是第几页,我就是想看看最后什么样子,那么就可以用(一定是显示20条):
以下是代码片段: SELECT * FROM pw_gbook WHERE uid=’48’ ORDER BY postdate ASC limit 20; |
首页这里就不在说了。
具体怎么实现搞明白了,就可以做PHP代码的修改了。稍稍修改一下,就会带来意想不到的效果。
这里只是一个通用的分页处理方法。不同的业务有可能还有不同的方法处理。如果在条件可能和情况可以考用:between … and .. 带代替limit分页操作。
第三种方法:
简单的逻辑转换。
以下是代码片段: SELECT * FROM pw_gbook WHERE uid=’48’ ORDER BY postdate DESC LIMIT 1275480,20; |
以下是代码片段: SELECT * FROM pw_gbook WHERE id>1275480 and uid=’48’ ORDER BY postdate DESC LIMIT 20; |
建议继续学习:
- MYSQL分页limit速度太慢优化方法 (阅读:4343)
- Mysql中的分页写法 (阅读:3906)
- 深入理解Linux内存管理机制(一) (阅读:3852)
- 独创比百度、Google分页还强的分页类 (阅读:3693)
- order by 与 limit 的优化 (阅读:3443)
- 高效的MySQL分页 (阅读:2755)
- 用Twitter的cursor方式进行Web数据分页 (阅读:2271)
- 交互模式之分页还是加载? (阅读:1996)
扫一扫订阅我的微信号:IT技术博客大学习
- 作者:wubx 来源: MySQL支持
- 标签: Limit 分页
- 发布时间:2009-11-30 09:08:21
- [66] Go Reflect 性能
- [65] Oracle MTS模式下 进程地址与会话信
- [64] 如何拿下简短的域名
- [59] android 开发入门
- [59] IOS安全–浅谈关于IOS加固的几种方法
- [58] 图书馆的世界纪录
- [58] 【社会化设计】自我(self)部分――欢迎区
- [53] 视觉调整-设计师 vs. 逻辑
- [47] 界面设计速成
- [46] 读书笔记-壹百度:百度十年千倍的29条法则