深度分页问题优化方案

问题原因

Mysql使用select * from table limit offset, rows分页在深度分页的情况下, 性能急剧下降。

例如:select * 的情况下直接⽤limit 600000,10 扫描的是约60万条数据,并且是需要回表 60W次,也就是说⼤部分性能都耗在随机访问上,到头来只⽤到10条数据(总共取600010条数据只留10条记录)

优化方案

前端方案:业务层面限制跨度比较大的跳页

提供2种风格分页器供用户选择

  1. 标准分页器,展示最后一页和跳转指定页输入框
    image.png
  2. 简单分页器
    image.png

参考
百度方案: 不展示最后一页和直接跳转指定分页的输入框
image.png
Google方案:只展示查看下一页的按钮
image.png

界面设计器选表格/画廊的属性面板提供分页器风格的属性下拉选择

image.png

xml示例
<!-- 表格使用的标准分页器 --> <view type="TABLE" paginationStyle="SIMPLE"> <!-- fields --> </view> <!-- 画廊使用默认的标准分页器 --> <view type="GALLERY" paginationStyle="STANDARD"> <!-- fields --> </view>

后端方案

  1. 使用索引:确保数据库表中的相关字段上创建了适当的索引。索引可以加快查询速度,特别是在处理大数据量时。

  2. 分批查询:将大数据分成多个较小的批次进行查询,而不是一次性查询全部数据。可以通过限制每次查询的数据量和使用合适的偏移量来实现分批查询,例如使用LIMIT和OFFSET子句。

  3. 基于游标的分页:使用基于游标的分页技术,而不是传统的偏移分页。游标分页是通过记录上一次查询的游标位置,在下一次查询时从该位置开始获取新的数据,避免了大偏移量的影响。这可以通过数据库自身的功能(例如MySQL的CURSOR)或使用第三方库来实现。

  4. 缓存数据:如果数据变化较少,可以考虑将查询结果缓存到内存中,以避免频繁地查询数据库。这样可以提高页面相应速度,并减轻数据库负担。缓存的数据应该根据业务需要及时更新。

  5. 数据预处理:如果查询结果经常需要进行复杂的计算或处理,可以考虑提前对数据进行预处理并缓存结果,以减少每次查询的计算负担。

  6. 数据库优化:针对具体数据库系统,可以根据实际情况进行数据库调优。例如,合理设置数据库连接池大小、调整数据库参数等。

  7. 分布式存储和计算:对于非关系型数据库或分布式存储系统,可以考虑使用分布式存储和计算方案,将数据分散存储在多个节点上,并通过计算节点并行处理查询请求,以提高性能和可伸缩性。

参考链接

MySQL深分页场景下的性能优化

Oinone社区 作者:原创文章,如若转载,请注明出处:https://doc.oinone.top/other/75.html

访问Oinone官网:https://www.oinone.top获取数式Oinone低代码应用平台体验

Like (0)
's avatar
Previous 2023年6月20日 pm4:07
Next 2023年11月2日 pm1:58

相关推荐

  • 序列化工具使用问题

    后端使用的JSON序列化JsonUtils.toJSONString(nodes);前端使用的JSON序列化PamirsJsonUtils.toJSONString(nodes, SerializerFeature.DisableCircularReferenceDetect, SerializerFeature.WriteDateUseDateFormat, SerializerFeature.BrowserCompatible);注意:用什么工具序列化,就用什么工具反序列化、parse 的时候,要保持一致, 使用PamirsJsonUtils序列化工具主要是为了解决枚举取值错误的问题以及id精度丢失问题。当出现这两个问题的时候,需要使用PamirsJsonUtils 进行序列化。

    2024年9月5日
    1.8K00
  • 无代码docker启动说明(5.1.0)

    1. 安装docker 1.1 Linux内核系统(以CentOS7为例) 1.1.1 检查防火墙 查看防火墙是否开启 systemctl status firewalld 如防火墙处于开启状态 有2种处理方式,选择其中一种,开发环境如内网环境建议选择处理方案1 处理方案1:停止防火墙 systemctl stop firewalld 处理方案2:开放docker镜像内置中间件透出的端口 88:web访问端口 8099:后端Java服务端口 19876:rocketmq的namesrv端口: 6378:缓存redis的端口 3307:数据库mysql的端口 2182:zookeeper的端口 20880:dubbo的通信端口 10991:rocketmq的broker端口 查看防火墙已经开放的端口 firewall-cmd –list-ports 防火墙新增开放端口示例: firewall-cmd –permanent –zone=public –add-port=88/tcp 新增以后生效需要重新加载防火墙 systemctl reload firewalld 查看端口是否开放成功 firewall-cmd –list-ports 也可以从外部使用telnet命令检查端口是否开放成功,如telnet 192.168.0.121 3307 1.1.2 官方安装地址(docker如已安装请忽略): https://docs.docker.com/engine/install/centos/ yum install -y yum-utils yum-config-manager –add-repo https://download.docker.com/linux/centos/docker-ce.repo 如果docker这个源异常可以用阿里云的源 #yum-config-manager –add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin #启动docker systemctl start docker #查看是否安装成功 docker -v 如果无法访问官网,参考阿里云安装Docker CE镜像https://developer.aliyun.com/mirror/docker-ce?spm=a2c6h.13651102.0.0.57e31b11lhSNtT 1.1.3 可使用一键安装脚本(docker如已安装请忽略) wget https://pamirs.oss-cn-hangzhou.aliyuncs.com/docker/quick-install.sh sh quick-install.sh 1.1.4 Docker部署常见问题 https://doc.oinone.top/install/20670.html 1.2 无公网环境Linux系统 需要根据指定的版本以及内核架构来生成对应docker以及镜像包 1.3 window环境 https://docs.docker.com/desktop/install/windows-install/ 2. 解压提供的部署.zip 部署.zip包含: settings-3.6.3.xml:拉取平台jar的maven仓库settings,对应maven版本3.6.x settings-3.8.x.xml:拉取平台jar的maven仓库settings,对应maven版本3.8.x oinone-op-ds-all-full:包含所有中间件及前后端工程,用于启动docker结构和脚本(需拷贝到服务器) oinone-op-ds-all-mini:仅包含前后端工程,用于启动docker结构和脚本(需拷贝到服务器) license:平台证书 docker-mvn-npm账号.md oinone-example:后端示例工程 ss-front-modules:前端示例工程 3. 对应版本的docker镜像拉取 镜像地址 镜像概述 harbor.oinone.top/oinone/oinone-designer-full-v5.1:5.1.16 包含所有中间件及前后端工程(v5.1:5.1.16为示例版本号,实际以Oinone发出来的为准) harbor.oinone.top/oinone/oinone-designer-mini-v5.1:5.1.16 仅包含前后端工程(v5.1:5.1.16为示例版本号,实际以Oinone发出来的为准) 注意:docker镜像拉取的账号密码在部署.zip里面(docker-mvn-npm账号.md) docker login –username=用户名 harbor.oinone.top docker pull harbor.oinone.top/oinone/xxx 4. 修改startup.sh/cmd文件 doker的结构包 oinone-op-ds-all-full 或oinone-op-ds-all-mini 上传到服务器上;下面的操作都是这该文件夹下进行 4.1 linux环境修改参数 在startup.sh文件中找到如下 configDir=$(pwd)version=版本号IP=192.168.0.121 修改对应的IP为docker宿主机IP 4.2 window环境修改参数 在startup.cmd文件中找到如下set configDir=%CD%set version=版本号set IP=192.168.0.121 修改对应的IP为docker宿主机IP 5. 修改mq/broker.conf 注意:使用oinone-op-ds-all-mini版本,无需进行该步操作(直接跳过)注意:使用oinone-op-ds-all-full版本,才需进行该步操作 修改其中brokerIP1的IP从192.168.0.121改成宿主机IP brokerClusterName = DefaultCluster namesrvAddr=127.0.0.1:9876 brokerIP1=192.168.0.121 brokerName = broker-a brokerId = 0 deleteWhen = 04 fileReservedTime = 48 …… 5. 修改config/application.yml 注意:使用oinone-op-ds-all-full版本,无需进行该步操作(直接跳过)注意:使用oinone-op-ds-all-mini版本,才需进行该步操作 修改中间件的配置(oinone-op-ds-all-full版本无需修改),把中间件对应的IP、端口或密码,改成实际提供服务IP、端口或密码。包括: zookeeper mysql rocket-mq redis oss配置 7. 启动Docker 7.1 linux环境启动 在终端执行 sh startup.sh 7.2 window环境启动 用PowerShell 执行 .\startup.cmd 7.3 查看日志,检查是否启动成功 在logs目录下可看到日志文件,第一次启动时间会相对长一些,等看到日志文件中输出 启动耗时…

    2024年8月19日
    2.6K00
  • 无网络环境下 RPM离线导出以及部署docker

    1.操作系统 以Centos7.6为例 [root@haibovm ~]# cat /etc/redhat-release CentOS Linux release 7.6.1810 (Core) [root@haibovm ~]# 2.安装yum-config-manager工具 系统默认没有安装这个命令 yum-config-manager ,这个命令在 yum-utils 包里。 yum -y install yum-utils 添加yum软件源信息(国内有很多,我这里添加阿里): yum-config-manager –add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 更新yum缓存 yum makecache fast 3.下载docker所有依赖到指定路径 mkdir -vp /opt/docker-rpm/ yum install docker-ce –downloadonly –downloaddir=/opt/docker-rpm/ 将所有的依赖rpm环境打包 cd /opt tar -czvf docker-ce-24-CentOS7.6-rpm.tar.gz docker-rpm/ 创建安装脚本install-docker-offline.sh #! /bin/bash cd /opt/docker-rpm yum -y localinstall *.rpm 4.在新的目标环境系统中,上传docker-ce-24-CentOS7.6-rpm.tar.gz 以及install-docker-offline.sh cd /opt tar zxvf docker-ce-24-CentOS7.6-rpm.tar.gz sh install-docker-offline.sh 安装完毕以后启动docker #查看启动状态(安装完默认未启动,需要手动执行启动命令) systemctl status docker # 启动docker systemctl start docker # 重新启动docker systemctl restart docker # 重新加载unit配置文件 systemctl daemon-reload

    2023年11月7日
    1.1K00
  • 自定义用户中心菜单

    使用扩展点实现用户中心菜单替换 1. 工程中引起pamirs-user-api <dependency> <groupId>pro.shushi.pamirs.core</groupId> <artifactId>pamirs-user-api</artifactId> </dependency> 2. 实现TopBarUserBlockAction的后置扩展 实现HookAfter后置扩展接口 @Hook(model = {TopBarUserBlock.MODEL_MODEL}, fun = {"construct"})添加Hook注解注明是TopBarUserBlock模型的construct函数的后置扩展。 增加用户中心菜单 @Component @Order(1) @SPI.Service public class MyTopBarActionExt implements TopBarActionExtendApi { public void edit(List<TopBarAction> list) { list.add(new TopBarAction("top_demo", "top.Teacher", "uiView9a0caf1d574a42c9847a057a0c4a4ad1", ActionTypeEnum.VIEW, 1) .setDisplayName("商品管理") .setIcon("oinone-gongzuotai") ); } } 实现效果 替换原有的用户中心菜单 替换原有的菜单跳转 @Component public class DemoTopBarUserBlockDataHookAfter implements HookAfter { @Override @Hook(model = {TopBarUserBlock.MODEL_MODEL}, fun = {"construct"}) public Object run(Function function, Object ret) { if (ret == null) { return null; } TopBarUserBlock result = null; if (ret instanceof Object[]) { Object[] rets = (Object[]) ((Object[]) ret); if (rets.length == 1) { result = (TopBarUserBlock) rets[0]; //例:替换用户中心:修改密码菜单 //使用name和model查询出模型的ViewAction替换修改密码ViewAction ViewAction demoViewAction = PamirsSession.getContext().getExtendCache(ActionCacheApi.class).get(Dog.MODEL_MODEL, "changePassword"); //设置菜单的icon Map<String, Object> attributes = Optional.ofNullable(demoViewAction.getAttributes()).orElse(new HashMap<>()); attributes.put("icon", "oinone-xiugaimima"); demoViewAction.setAttributes(attributes); //UserViewAction第0个是修改密码ViewAction,使用自定义的ViewAction就可以实现替换 result.getUserViewAction().set(0, demoViewAction); } } else { result = (TopBarUserBlock) ret; } return result; } } 使用@UxRouteButton方式新增ViewAction,更多新增Action方式详见:Action的类型 @Model.model(Dog.MODEL_MODEL) @Component @UxRouteButton( action = @UxAction(name = "changePassword", displayName = "修改密码"), value = @UxRoute(model = Dog.MODEL_MODEL, openType = ActionTargetEnum.DIALOG)) public class DogAction { } 替换原有的个人设置头像跳转 修改点击头像绑定的跳转逻辑 @Order(10) @Component @SPI.Service public class DemoTopBarUserBlockDataApi implements TopBarUserBlockDataApi { @Override public TopBarUserBlock extendData(TopBarUserBlock data) { //例如增加一个菜单, PamirsDemo.MODEL_MODEL: 模型。 MenuuiMenu31f22466735a4abe8e0544b428ed88ac:viewAction的name。 Action demoViewAction =…

    2024年7月4日
    2.1K00
  • 开放接口怎么使用

    开放接口的具体使用 第一步将接口授权的应用变成启用状态 第二步点击查看密钥,复制API Key与API Secret 第三步利用复制下来的API Key与API Secret生成token 第四步调用开放接口

    2023年11月7日
    95800

Leave a Reply

Please Login to Comment