postgresql之翻页优化

列表和翻页是所有应用系统里面必不可少的需求,但是当深度翻页的时候,越深越慢。下面是几种常用方式

准备工作

CREATE UNLOGGED TABLE data (
   id bigint GENERATED ALWAYS AS IDENTITY,
   value double precision NOT NULL,
   created timestamp with time zone NOT NULL
);

/* 设置随机数种子 */
SELECT setseed(0.2740184);
/* 初始化数据 */
INSERT INTO data (value, created)
SELECT random() * 1000, d
FROM generate_series(
        TIMESTAMP '2022-01-01 00:00:00 UTC',
        TIMESTAMP '2022-12-31 00:00:00 UTC',
        INTERVAL '1 second'
     ) AS d(d);

/* 添加主键 */
ALTER TABLE data ADD PRIMARY KEY (id);

/* 回收空间,并对表数据进行统计分析 */
VACUUM (ANALYZE) data;

我们的查询目标是下面的SQL

SELECT value, created
FROM data
WHERE value BETWEEN 0 AND 10
ORDER BY created;

为了加速查询我们可以创建对应索引

CREATE INDEX data_created_value_idx ON data
   (created, value);

简单分页 LIMIT ? OFFSET ?

这是第一种方式

-- 首页
SELECT value, created
FROM data
WHERE value BETWEEN 0 AND 10
ORDER BY created
LIMIT 50;
-- 第 深n 页
SELECT value, created
FROM data
WHERE value BETWEEN 0 AND 10
ORDER BY created
OFFSET 180000 LIMIT 50;

不论是mysql 还是pg数据库 直接使用offset limit 这种查询的时候都是扫描处理前 n * pageSIze 数据然后丢弃前面 (n-1) * pageSize页的数据,数据库是否使用索引是有优化策略的,当经过一系列复杂的预估之后,假如数据库优化器 判定 走索引还没全表扫描效率高的时候就会放弃走索引,这个时候我们的查询就会比较慢,基本上都是秒级别的了
上面两个sql的执行计划如下
在这里插入图片描述
在这里插入图片描述
全表扫描最大的问题不仅仅是某个查询慢,更严重的是会导致锁表

缺点

  • 页码越深,性能越差,但是假如用户只关心前面几页的数据,是没有什么问题的
  • 并发情况下翻页会有跳数据或者重复数据的问题,比如用户A是在查看数据翻页的,用户B在第一页加了一条数据,这个时候用户A翻页,那么原来第一页最后的数据就会被挤到第二页,类似这种情况,但是一般的时候非高并发情况可以不考虑

优点

简单,不管怎么翻都一招鲜 吃遍天

使用游标 WITH HOLD CURSORS

WITH HOLD CURSORS是一种特殊的游标,与普通游标主要区别如下

  • 普通游标:普通游标(或称为会话级游标)的生命周期通常与创建它的事务相同。这意味着,当事务提交或回滚时,游标也会被关闭,其相关的资源会被释放。
  • WITH HOLD CURSORS:WITH HOLD游标在事务结束后仍然保持打开状态,即使原始事务已经提交或回滚。这使得游标可以在多个事务之间保持活动状态,直到显式关闭或会话结束
    但是在分页情况下我们一般一页是一个请求,这个时候肯定是不同的事务,所以这个时候普通游标是无法满足我们的要求的
    我们使用WITH HOLD CURSORS
DECLARE c SCROLL CURSOR WITH HOLD FOR
SELECT value, created
FROM data
WHERE value BETWEEN 0 AND 10
ORDER BY created;

在这里插入图片描述
获取任意数据

-- 移动游标
MOVE ABSOLUTE 4950 IN c;
-- 获取数据
FETCH 50 FROM c;

注意继续FETCH会继续后翻页
在这里插入图片描述
还需要注意的是这个游标用完可一定要关闭、关闭;关闭,重要的事情说三遍

-- 关闭游标
CLOSE c;

优点

  • 适用于所有查询,不管是第一页还是最后一页,效率一样
  • 结果集是稳定的,没有像OFFSET和LIMIT那样跳过或重复结果
  • 可以跳页,从第5页,直接跳到第100页

缺点

  • 当完成操作时,一定不要忘记关闭游标,否则结果集将保存在服务器上,直到数据库会话结束
  • 如果游标长时间打开,数据将变的陈旧,无法获取动态的最新数据
  • 游标长时间打开,相当于一个长事务

KEYSET PAGINATION

暂时翻译为位点,原理上就是记录上一次数据最后一条内容,所以,这个值必须是唯一的强有序的,这样翻页的时候才不会重复或者跳过数据

-- 首页查询
SELECT id, value, created
FROM data
WHERE value BETWEEN 0 AND 10
ORDER BY created, id
LIMIT 50;

-- 基于上面位点的下一页
SELECT id, value, created
FROM data
WHERE value BETWEEN 0 AND 10
  AND (created, id) > ('2022-01-01 01:27:35+01', 5256)
ORDER BY created, id
LIMIT 50;

在这里插入图片描述
位点查询
在这里插入图片描述
如果使用这种方式的话我们添加这个索引效率会更好

CREATE INDEX data_keyset_idx ON data
   (created, id, value);

优点

  • 每次查询只获取我们需要的数据,不需要扫描不额外的数据,减少了相关资源代价
  • 每个查询将展示最新并发数据修改的当前数据

缺点:

  • 需要一个专门为查询而设计的特殊索引
  • 需要对业务进行改造只有事先能获取到确切的位点,查询时才有用,并且当我们修改排序字段或者条件的时候,这个位点可能跟之前的就不一致了。
  • 前后端都需要改造

其他

一般情况下我们可能也需要count这个值,上面三种方式中WITH HOLD CURSORS是天然支持的

MOVE ALL IN c;

在这里插入图片描述
剩下两种都是扫描全表,使用昂贵的资源,简单点跟产品battle 不支持,tips:对于ES深度翻页,直接limit比PG,MySQL资源更严重,因为ES会在每个分区上进行计算到协作节点进行统一聚合,所以一般的ES可能会关闭这种深度分页或者使用游标,类似Feed流,下一个下一个。整体思想是一致的。

参考

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/698554.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

matlab 异常值检测与处理——Z-score法

目录 一、算法原理1、算法概述2、主要函数3、参考文献二、代码实现三、结果展示四、相关链接本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫。 一、算法原理 1、算法概述 使用Z分数法,可以找出距离平均值有多少个标准差值…

Java面试八股之静态变量和实例变量的区别有哪些

Java静态变量和实例变量的区别有哪些 存储位置和生命周期: 静态变量:静态变量属于类级别,存储在Java的方法区(或称为类区,随JVM实现而异,现代JVM中通常在元数据区内),并且在类首次…

天锐绿盾,怎么防止公司内部核心文件、文档、设计图纸、源代码、音视频等数据资料外泄

天锐绿盾通过多种技术和管理手段,全面保护公司内部的核心文件、文档、设计图纸、源代码、音视频等数据资料,防止外泄。以下是具体的防泄密措施: PC地址: https://isite.baidu.com/site/wjz012xr/2eae091d-1b97-4276-90bc-6757c5d…

【技术干货】Linux命令“du-sh和df”执行结果存在差异,问题分析及处理过程

1.du-sh和df的差异 du和df是两个不同的Linux命令,它们⽤于查看磁盘空间的使⽤情况。但是它们有⼀些区别: • du(diskusage)会扫描每个⽂件和⽬录,并计算它们的总⼤⼩。[1]du-sh*会显⽰当前⽬录下每个⽂件或⽬录的⼤⼩…

APD系列特高频局放监测装置

安科瑞电气股份有限公司 祁洁 15000363176 一、产品概述 现阶段,电力系统对于电能的质量提出越来越高的要求,不仅要确保供电稳定可靠,而且供电的安全性也是重要要求。电力系统中,金属封闭开关设备得到广泛应用,因…

基于springboot实现影院订票系统项目【项目源码+论文说明】

基于springboot实现影院订票系统演示 摘要 现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处理数据信息的管理方式。本影院订票系统就是在这样的大环境下诞生,其可以帮助管理者在…

安卓手机电脑同步数据,2个方法,有效避免数据膨胀

如今,我们的手机已经成为了数字生活的中心舞台,而电脑则是我们工作和娱乐的得力助手。两者之间的数据同步,就像是搭建了一座无形的桥梁,让我们的生活和工作变得更加便捷和高效。如何高效进行手机电脑同步数据呢?在这篇…

第十三章 组合模式

目录 1 组合模式介绍 2 组合模式原理 3 组合模式实现 4 组合模式应用实例 5 组合模式总结 1 组合模式介绍 组合模式(Composite Pattern) 的定义是:将对象组合成树形结构以表示整个部分的层次结构.组合模式可以让用户统一对待单个对象和对象的组合. 2 组合模式…

【C++题解】1457 - 子数整除

问题:1457 - 子数整除 类型:循环应用 题目描述: 于一个五位数 abcde ,可将其拆分为三个子数: sub1abc sub2bcd sub3cde 例如,五位数20207 可以拆分成sub1202 sub2020 (也就是 20) sub3207 现在给定一个正…

中文词云MATLAB

wordcloud Create word cloud chart from text, bag-of-words model, bag-of-n-grams model, or LDA model name{1} {数字图像处理}; name{2} {禹晶 肖创柏 廖庆敏}; name{3} {1 绪论,2 数字图像基础,3 空域图像增强,4 频域图像增强,7 图像压缩编码,9 二值图像形态学,8 图像…

k8s学习--kubernetes服务自动伸缩之水平收缩(pod副本收缩)VPA策略应用案例

文章目录 前言应用环境1.VPA应用案例 updateMode: "Off"(1)创建应用实例(2)创建vpa 2.VPA应用案例 updateMode: "Auto"(1)创建应用 (2)创建vpa(3&am…

护眼台灯哪个品牌好?几款性价比最高的护眼台灯推荐

在过去,科技尚未发展至如今这般先进水平时,晚上需要照明的时候,我们通常只能依赖白炽灯。尽管白炽灯以其低成本和接近自然光的显色性获得了一定的青睐,随着时代的发展,现在市面上出现了更为护眼的选择——LED台灯。然而…

VMware导入vmdk文件(亲测有效)

场景:从别的地方拷贝了一个系统镜像,实际测试案例是从vulnhub下载的Kioptix Level #4靶场解压缩以后的文件是【Kioptrix4_vmware.vmdk】后缀为名为vmdx,使用常规的方式【文件-----打开】的方式,不能导入虚拟机,现在演示如何导入到…

intel新CPU性能提升68%!却在内存上违反祖训

前几天的台北电脑展「Computex」,各家都拿出了看家本领。 老朋友 AMD 在会展上发布了最新的锐龙 9000 系列和自己家移动处理器 HX AI 系列,IPC 和能效都取得了不错的进步。 当然隔壁蓝厂 intel 也没闲着,当即就掏出了下一代的低功耗移动端处…

【SQL边干边学系列】05高级问题

文章目录 前言回顾高级问题32.高价值客户33.高价值的客户-总订单数34.高价值的客户-带有折扣35.月末订单36.具有许多详细信息行的订单 答案32.高价值客户33.高价值的客户-总订单数34.高价值的客户-带有折扣35.月末订单36.具有许多详细信息行的订单 未完待续 前言 该系列教程&am…

GaussDB技术解读——GaussDB架构介绍(二)

上篇图文,从GaussDB关键架构目标、GaussDB分布式架构、数据计算路由层(Coordinator)关键技术方案等三方面对GaussDB架构进行了介绍。本篇将从数据持久化存取层(DataNode)关键技术方案、全局事务管理层(GTM)关键技术方案…

大一学生分享网络编程聊天室-简单私聊

每天过得充实,你将不会焦虑 ---同行者联盟 Socket 是一种规范(标准),封装了TCP协议的通信细节,使得我们使用它就可以完成与远端计算机的TCP链接,以及数据的传输。并且可以完成数据传输基于双向流的读写操作,Java语言…

揭秘:全自动阅读挂机项目,号称自动阅读一天窗口10-50+(脚本+教程)

首先,我们需要对全自动阅读挂机项目有一个基本的认识。这是一个高效利用时间和精力,使阅读成为一种被动行为的新型项目。它将阅读与电脑操作结合,通过挂机的方式,使得在忙碌的生活中仍能保持高效学习。 1.全自动阅读挂机项目背后…

G5 - Pix2Pix理论与实战

🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 目录 理论知识图像翻译CGANU-NetPix2Pix损失函数模型结构生成器差别器 模型效果总结与心得体会 理论知识 前面已经学习了GAN与CGAN,这节开始学习P…

linux使用crontab定时执行url

在Linux操作系统中,Crontab是一个非常实用的工具,可以帮助用户定时执行任务,以达到自动化管理系统的目的。而在使用Crontab时,有时候我们可能需要让系统定时访问某个URL,以实现特定的功能或操作。本文将介绍如何使用Cr…