在MySQL中使用LIMIT进行分页的方法
作者:吴炳锡 发布时间:2024-01-20 22:27:58
今天看一个水友说他的MySQL现在变的很慢。问什么情况时。说单表超过2个G的一个MyISAM。真垃圾的回答方式。
简单答复:换一个强劲的服务器。换服务器很管用的:)
………
最终让取到慢查询:
SELECT * FROM pw_gbook WHERE uid='N' ORDER BY postdate DESC LIMIT N,N;
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;
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-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;
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;
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;
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;
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;
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;
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 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;
SELECT * FROM pw_gbook WHERE id>1275480 and uid='48' ORDER BY postdate DESC LIMIT 20;


猜你喜欢
- 学习 Go 语言的开发者越来越多了,很多小伙伴在使用时,就会遇到种种不理解的问题。其中一点就是包的循环引用的报错:package comma
- 计算表达式:1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/
- 问题缘由:负责公司的开发平台研发工作,考虑的知识产权的保护工作,必须要考虑java的加密技术和js脚本的加密技术。在目前java加密很容易破
- 什么是树表查询?借助具有特殊性质的树数据结构进行关键字查找。本文所涉及到的特殊结构性质的树包括:二叉排序树。 平衡二叉树。使用上述树结构存储
- 构筑专业的网络站点和应用程序,先进的设计工具,功能强大,开放式集成系统;流畅的开发进程。Macromedia Dreamweaver MX
- 我们通常可以使用os模块的命令进行执行cmd方法一:os.systemos.system(执行的命令)# 源码def system(*arg
- 本文为大家分享了mysql 8.0.20 winx64安装配置方法,记录如下。MySQL官网:链接直接点击链接也可以下载:mysql 8.0
- 前言这篇来学习正则表达式的替换和分组功能,替换很好理解,分组有点复杂,特别是如何写有效的分组的正则表达式。这篇通过几个练习,简单了解下替换和
- WebSocketWebSocket说明WebSocket 是全双工网络通信通信协议,实现了客户端和服务器的平等对话,任何一方都可以主动发送
- 前言亲人工作考试,公司给的题库好像是直接从数据库导出的表格Excel形式,在移动端上非常难看,需要不断左右上下滑动,看不了多少题眼就瞎了,遂
- 一、OS包的作用os包中的API主要可以帮助我们使用操作系统中的文件系统、权限系统、环境变量、系统进程,以及系统信号。对于类Unix的操作系
- 数据库: 30万条,有ID列但无主键,在要搜索的“分类”字段上建有非聚集索引 过程T-SQL: /* 用户自定义函数:执行时间在1150-1
- 一基础理解: var e = document.getElementById("selectId");e. option
- 本文实例为大家分享了SpringBoot整合Mybatis使用Druid数据库连接池的方法,具体内容如下在SpringBoot项目中,增加如
- 有以下一个表movestar(id,name,title,address),内容为:现在要查找所有具有相同的title和address的人s
- 首先 下载 jedis.jar包然后再 工程设置里面找到Libraries,点击+。添加下载好的jedis.jar包。点击OK退出即可创建J
- 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技
- json 模块Python 提供了内置的 json 模块来处理 JSON 格式的文件。该模块主要分为读取和写入 JSON 文件。读取 JSO
- 也许光从字面上来说,版式设计中的“亲密性”似乎不太好理解,正常的情况下,我们都会把“亲密性”理解为人与人之间的关系的一种表现,事实上在版式设
- 一看,C盘只有不到2M可用空间,一查原因,sqlserver安装路径下的log目录文件占了好大,5G多, 于是上网搜了下,解决了: 把与sq