IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

合理使用MySQL的Limit进行分页

MySQL支持 2009-11-30 09:08:21 累计浏览 4,028 次
本机暂存

     今天看一个水友说他的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;
 
    这样来查询第6页的内容。同样对于查看第4页的内容(假设第5页的最大日期为:2009-11-3)则第4页的内容为:
 
以下是代码片段:
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;
 
 
     看到这里明白为什么大型网站的分页不是一下标识出来完了,让都能点了吧。也不会给你一个框让你输入一个页跳过去了。如果跳的页面过多,也就存在N值过大的问题了。所以要想办法必免。

    第三种:显示 “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;

同分类推荐文章

  1. 使用deepseek进行Oracle恢复,引起重大故障 (2026-06-22 10:56:00)
  2. 接手一个只差临门一脚的数据库恢复 (2026-06-18 00:13:09)
  3. 我做了一个 AI 版的 StarRocks 升级风险扫描工具,直接帮我定位到一个风险 (2026-06-15 01:00:00)

查看更多 数据库 文章 →

建议继续学习

  1. 用Hyer来进行网站的抓取 (累计阅读 158,252)
  2. MySQL数据库在实际应用一些方面的介绍 (累计阅读 36,399)
  3. WordPress插件开发 -- 在插件使用数据库存储数据 (累计阅读 29,164)
  4. Mysql监控指南 (累计阅读 21,351)
  5. 由浅入深探究mysql索引结构原理、性能分析与优化 (累计阅读 16,523)
  6. 在Apache2.2.XX下安装Mod-myvhost模块 (累计阅读 13,058)
  7. 15个最好的免费开源电子商务平台 (累计阅读 12,541)
  8. 浅谈MySQL索引背后的数据结构及算法 (累计阅读 11,908)
  9. 整理了一份招PHP高级工程师的面试题 (累计阅读 11,709)
  10. 深入浅出INNODB MVCC机制与原理 (累计阅读 9,693)