对于数据库相关的业务,逃不过的数据分页场景,无论是前台分页浏览还是划到页面底部自动加载。对于分页需求,各数据库也提供了成熟的SQL支持,类似于Hibernate等ORM框架也集成了相关的方法。但是基于数据库(框架)提供的分页方法,我们能否结合业务,提供更高效更优化的分页方法呢?

基础分页技术

数据查询语句中,和分页相关的有两个参数,分别是:

Limit:查询数据条数

OFFSET:查询结果数据起始位置偏移量(跳过的行数)

MySQL中的语法:

SELECT fields_list FROM table_name [ ORDER BY ... ]

[LIMIT offset, limit];

但这个语法不兼容PostgreSQL,兼容MySQL和PostgreSQL的语法为:

SELECT fields_list FROM table_name [ ORDER BY ... ]

[ LIMIT {number | ALL} ] [ OFFSET number];

注:LIMIT和OFFSET都是可选字段。

下文以第二种兼容的语法来进行描述。本文示例的数据库表信息如下:

示例表为订单表,表名:orders,每页显示条数:10 page_sieze。

查询第一页:

SELECT * FROM orders ORDER BY order_id

LIMIT 10 OFFSET 0;

查询第二页:

SELECT * FROM orders ORDER BY order_id

LIMIT 10 OFFSET 10;

查询第n页:

SELECT * FROM orders ORDER BY order_id

LIMIT page_sieze OFFSET page_sieze * n;

分页优化

如果熟悉Openstack API的开发人员会注意到,Openstack原生API采用了特殊的分页方式:Openstack分页以limit和marker两个字段进行控制,limit控制每页显示数量,marker标识数据起始位置,即本分页第一条数据的ID。

以nova list的API为例,官方对两个字段的说明如下:

Nova List API

Limit字段说明

Requests a page size of items. Returns a number of items up to a limit value. Use the limit parameter to make an initial limited request and use the ID of the last-seen item from the response as the marker parameter value in a subsequent limited request.

Marker字段说明

The ID of the last-seen item. Use the limit parameter to make an initial limited request and use the ID of the last-seen item from the response as the marker parameter value in a subsequent limited request.

以上描述中的关键信息是:如果分页查询,返回的JSON格式中会包含marker字段,指示下一页数据第一条数据的ID。另外这个API也存在一个限制,就是分页时,只能浏览上一页/下一页,而不能跳页。

不过借鉴这个思路,我们可以对某些场景的分页查询进行优化。

对于按需自动加载(划到页面底部自动加载更多内容)或者只提供上一页/下一页浏览模式的场景,可以进行如下优化:

每次查询数据时,我们记录最后一条数据的ID或最后更新时间(这个主要根据order by字段来确定)

加载下一页数据时,把本页的最后一条数据ID作为过滤条件。

加载上一页数据时,则把本页第一条数据ID作为过滤条件。

查询下一页

SELECT * FROM orders WHERE order_id > page_last_id ORDER BY order_id

LIMIT page_sieze OFFSET 0;

查询上一页

SELECT * FROM orders WHERE order_id < page_first_id ORDER BY order_id

LIMIT page_sieze OFFSET 0;

小技巧:每次查询数据时,多返回一条数据,即返回page_size + 1条数据,但显示时去掉最后一条数据,通过这多出来一条数据,我们可以用来判断数据是否还有下一页。

另外对于可以跳转到任意页面的场景,也可以进行优化,这种可跳转场景,分页显示也是有限的,一般模式是第一页/上一页/当前页前后10页……/下一页/最后一页,也就是说,分页时,数据是在一定范围内(前后10页)移动,可以以当前页数据为基础,对数据进行过滤,减少数据扫描范围。

考虑orders表有10W条记录,每页显示10条,当前页码为1000时的场景,如果按照单独limit和offset模式,offset=1W,也就是数据库要扫码1W条记录。假如现在翻页要从1000页跳转到1005页,我们以第1000页最后一条数据ID为过滤条件,offset跳过1001-1004的40条数据即可。

查询1005页

SELECT * FROM orders WHERE order_id > page_1000_last_id ORDER BY order_id

LIMIT page_sieze OFFSET page_size * 4;

这种方法相比基础的分页方式,只要order by字段是主键或索引字段,数据扫描的行数从1W多条下降到了几十条,效率大大提升。

mysql 高效分页查询_PostgreSQL、MySQL高效分页方法探讨相关推荐

  1. 【MySQL Tips】偏移量大的分页查询LIMIT子句的优化方法

    SQL优化是要看执行计划分析,并做基准测试的. 前言 MySQL官方关于LIMIT子句的优化建议在之前的文章中写过,链接如下: 8.2.19 LIMIT查询优化.note [MySQL 8翻译]8.2 ...

  2. oracle分页查询sql语句通用,oracle分页查询sql语句,oracle分页查询sql语句详解

    oracle分页查询sql语句,oracle分页查询sql语句详解,Oracle分页查询sql语句 Oracle中分页和MySql中的分页不同,MySql中的分页使用关键字limit即可,相对简单一点 ...

  3. springboot controller 分页查询_Spring Boot实战分页查询附近的人: Redis+GeoHash+Lua

    您的支持是我不断创作巨大动力 CSDN博客地址(关注,点赞) 人工智能推荐 GitHub(Star,Fork,Watch) 前言 最近在做社交的业务,用户进入首页后需要查询附近的人: 项目状况:前期尝 ...

  4. php redis 分页查询,redis如何解决分页查询

    我们都知道,通过缓存查询的结果,可以极大的提升系统的服务能力,以及降低底层服务或者是数据库的压力.对于有分页条件的缓存,我们也可以按照不同的分页条件来缓存多个key. 基于SortedSet的分页查询 ...

  5. mysql分页查询减轻压力_mysql分页查询优化

    在实际的项目中,分页查询是在寻常不过的,甚至说不可避免的.通常数据量较少的时候,很难遇到效率的影响.但是当数据量较大时,一个普通的分页sql能让你恶心到家. 我们常用的分页sql如下: 1 SELEC ...

  6. mysql关联表分页查询_MySQL一对多分页查询-主表关联表条件查询问题

    文章目录 1 摘要 2 情景复现 2.1 数据模型 2.2 核心代码 2.3 测试数据 2.4 拓展一点 1 摘要 分页查询是后台项目中最常见的一种操作,在一对多(one to many)的关系表中, ...

  7. mysql中怎么分页查询_mysql怎样实现分页查询

    mysql分页查询的方法:1.用具体字段代替[*]:2.先查寻索引:3.使用[between - and],id必须是连续递增的:4.保留上一页记录所在id. mysql分页查询的方法: 简述通常在M ...

  8. ORACLE分页查询SQL语法——高效的分页

    --1:无ORDER BY排序的写法.(效率最高) --(经过测试,此方法成本最低,只嵌套一层,速度最快!即使查询的数据量再大,也几乎不受影响,速度依然!) SELECT * FROM (SELECT ...

  9. mysql中in查询效率低的替代方法_一波骚操作,我把 SQL 执行效率提高了 10,000,000 倍...

    场景 我用的数据库是mysql5.6,下面简单的介绍下场景 课程表: 数据100条 学生表: 数据70000条 学生成绩表SC 数据70w条 查询目的:查找语文考100分的考生 查询语句: selec ...

最新文章

  1. iOS 直播专题5-推流
  2. 计算机桌面文件夹删除如何找回,电脑删除文件如何恢复 误操作的一剂后悔药...
  3. 策略模式原来这么简单!
  4. POJ 1741 Tree(点分治)
  5. 如何在Netweaver SE16里直接查看某数据库行记录 1
  6. Bing与DuckDuckGo搜索结果惊人一致?Google展现强势差异
  7. 多台Linux服务器之间互相免密登陆
  8. 软件测试基础课程学习笔记1--软件测试简介
  9. C4D立体数字设计灵感,适合庆典应用|这波用得6啊!
  10. Python 3 进阶 —— print 打印和输出
  11. 巧用ASP.NET预编译Web应用程序规避调用延迟,徐汇区网站设计
  12. Asp.Net删除文件夹后引起Session丢失的解决办法
  13. 数学建模6 典型相关分析
  14. 手机QQ2009(塞班第三版)聊天记录提取完全代码
  15. HTTP协议格式详解
  16. Jmeter 添加kafka支持
  17. 微信SDK非ipad协议
  18. scrum立会报告+燃尽图(第二周第三次)
  19. html锚点链接怎么互点,通过优化网页核心关键词快速提升排名
  20. mastercamx9专用程序单,mastercamx9程式单

热门文章

  1. SAP Credit Memo Debit Memo
  2. SAP BW数据源增强管理
  3. abap 在table control(表控件) 实现查找功能
  4. 永洪Desktop一个工具就可搞定中国式复杂报表需求
  5. 将列表转成数组_漫画 | 什么是散列表(哈希表)?
  6. 怎么看电脑电源多少w_电脑电源怎么测试通电
  7. java线程数翻倍性能翻倍_术业专攻 | 如何让Java Web性能翻倍?
  8. python print %s 号格式化输出
  9. Python 重写父类方法
  10. python3字符串的常见操作