深度分页问题优化方案

问题原因

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低代码应用平台体验

(0)
的头像
上一篇 2023年6月20日 pm4:07
下一篇 2023年11月2日 pm1:58

相关推荐

  • 自定义RSQL占位符(placeholder)及在权限中使用

    1 自定义RSQL占位符常用场景 统一的数据权限配置 查询表达式的上下文变量扩展 2 自定义RSQL的模板 /** * 演示Placeholder占位符基本定义 * * @author Adamancy Zhang at 13:53 on 2024-03-24 */ @Component public class DemoPlaceHolder extends AbstractPlaceHolderParser { private static final String PLACEHOLDER_KEY = "${thisPlaceholder}"; /** * 占位符 * * @return placeholder */ @Override public String namespace() { return PLACEHOLDER_KEY; } /** * 占位符替换值 * * @return the placeholder replace to the value */ @Override protected String value() { return PamirsSession.getUserId().toString(); } /** * 优先级 * * @return execution order of placeholders, ascending order. */ @Override public Integer priority() { return 0; } /** * 是否激活 * * @return the placeholder is activated */ @Override public Boolean active() { return true; } } 注意事项 在一些旧版本中,priority和active可能不起作用,为保证升级时不受影响,请保证该属性配置正确。 PLACEHOLDER_KEY变量表示自定义占位符使用的关键字,需按照所需业务场景的具体功能并根据上下文语义正确定义。 为保证占位符可以被正确替换并执行,所有占位符都不应该出现重复,尤其是不能与系统内置的重复。 3 占位符使用时的优先级问题 多个占位符在进行替换时,会根据优先级按升序顺序执行,如需要指定替换顺序,可使用Spring的Order注解对其进行排序。 import org.springframework.core.annotation.Order; @Order(0) 4 Oinone平台内置的占位符 占位符 数据类型 含义 备注 ${currentUser} String 当前用户ID 未登录时无法使用 ${currentRoles} Set<String> 当前用户的角色ID集合 未登录时无法使用 5 如何覆盖平台内置的占位符? 通过指定占位符的优先级,并定义相同的namespace可优先替换。 6 如何定义会话级别的上下文变量? 在上述模板中,我们使用的是Oinone平台内置的上下文变量进行演示,通常情况下,我们需要根据实际业务场景增加上下文变量,以此来实现所需功能。 下面,我们将根据当前用户获取当前员工ID定义该上下文变量进行演示。 /** * 员工Session * * @author Adamancy Zhang at 14:33 on 2024-03-24 */ @Component public class EmployeeSession implements HookBefore { private static final String SESSION_KEY = "CUSTOM_EMPLOYEE_ID"; @Autowired private DemoEmployeeService demoEmployeeService; public static String getEmployeeId() { return PamirsSession.getTransmittableExtend().get(SESSION_KEY);…

    2024年3月24日
    1.7K00
  • 5.0.4版本feature:新增协同开发版本保护功能,请升级对应版本

    版本号: 5.0.9 版本发布日期:2024.07.25更新要点:默认导出模板与最高优先级表格视图保持一致 5.0.9 版本 升级说明及步骤(已升级为5.0.0版本忽略) 此版本与4.7.8版本的兼容方案如下,请严格参照升级说明及步骤进行1、【重要】升级前备份base库和用户权限模块所在的库 2、【重要】升级过程执行SQL严格按照升级文档中的步骤执行。特别注意:部分SQL是要求【发布前执行】,部分SQL是要求【发布后执行】 5.0.0升级详细说明及步骤 升级内容(5.0.0) 新增协同开发版本保护功能 新增协同开发元数据保护功能 新增自动全量判断功能 修复协同开发若干问题 大幅优化启动时间及Redis内存消耗 请尽可能保证业务工程前后端服务以及设计器同步升级前端服务仅需重新执行npm install即可自动升级到最新版本 版本包信息 Oinone平台部署及依赖说明(v5.0) 未使用到的版本号请忽略,按项目中使用到的进行替换。 <!– 平台基础 –> <pamirs.middleware.version>5.0.2</pamirs.middleware.version> <pamirs.k2.version>5.0.8</pamirs.k2.version> <pamirs.framework.version>5.0.22</pamirs.framework.version> <pamirs.boot.version>5.0.13</pamirs.boot.version> <pamirs.distribution.version>5.0.5</pamirs.distribution.version> <!– 平台功能 –> <pamirs.metadata.manager>5.0.1</pamirs.metadata.manager> <pamirs.core.version>5.0.30</pamirs.core.version> <pamirs.workflow.version>5.0.9</pamirs.workflow.version> <pamirs.workbench.version>5.0.3</pamirs.workbench.version> <pamirs.data.visualization.version>5.0.3</pamirs.data.visualization.version> <!– 设计器 –> <pamirs.designer.common.version>5.0.4</pamirs.designer.common.version> <pamirs.flow.designer.base.version>5.0.3</pamirs.flow.designer.base.version> <pamirs.workflow.designer.version>5.0.2</pamirs.workflow.designer.version> <pamirs.model.designer.version>5.0.2</pamirs.model.designer.version> <pamirs.ui.designer.version>5.0.11</pamirs.ui.designer.version> <pamirs.data.designer.version>5.0.2</pamirs.data.designer.version> <pamirs.dataflow.designer.version>5.0.3</pamirs.dataflow.designer.version> <pamirs.eip.designer.version>5.0.4</pamirs.eip.designer.version> 注意镜像名称变化 镜像说明 所有镜像均使用docker manifest支持amd64和arm64架构。如镜像拉取过慢,可在对应镜像Tag添加-amd64、-arm64后缀获取单一架构镜像。 docker pull harbor.oinone.top/oinone/oinone-designer-full-v5.0:5.0.9.2-amd64 docker pull harbor.oinone.top/oinone/oinone-designer-full-v5.0:5.0.9.2-arm64 镜像拉取 镜像或JAR版本:5.0.9.2 体验镜像:(所有中间件及前后端服务,包含全部设计器) docker pull harbor.oinone.top/oinone/oinone-designer-full-v5.0:5.0.9.2 部署镜像:(包含前后端服务,包含全部设计器) docker pull harbor.oinone.top/oinone/oinone-designer-mini-v5.0:5.0.9.2 流程设计器镜像:(包含前后端服务,仅包含流程设计器) PS:原workflow-designer-standard-v5.0镜像不再提供,请更换为该镜像。 docker pull harbor.oinone.top/oinone/workflow-designer-v5.0:5.0.9.2 后端镜像:(仅包含后端服务,包含全部设计器) docker pull harbor.oinone.top/oinone/designer-backend-v5.0:5.0.9.2 前端镜像:(仅包含前端服务,包含全部设计器) PS:前端镜像版本为独立版本,与其他镜像版本不同。原基础镜像为nginx-1.21.0版本,从5.0.8版本开始使用nginx-1.24.0版为基础镜像 docker pull harbor.oinone.top/oinone/designer-frontend-v5.0:5.0.18 独立部署所有设计器JAR:(后端服务,包含所有设计器)pamirs-designer-boot-v5.0-5.0.9.2.jarpamirs-designer-boot-v5.0-latest.jar 独立部署流程设计器JAR:(后端服务,仅包含流程设计器)pamirs-workflow-designer-boot-v5.0-5.0.9.2.jarpamirs-workflow-designer-boot-v5.0-latest.jar 后端无代码设计器Jar包启动方法 如果您有任何问题、建议或反馈,请随时联系我们。为了获得最佳体验,请及时更新至最新版本。我们将继续努力改进产品,提供更好的服务。谢谢!

    2024年7月25日
    1.1K00
  • 4.2.2 框架之MessageHub

    一、MessageHub 请求出现异常时,提供”点对点“的通讯能力 二、何时使用 错误提示是用户体验中特别重要的组成部分,大部分的错误体现在整页级别,字段级别,按钮级别。友好的错误提示应该是怎么样的呢?我们假设他是这样的 与用户操作精密契合 当字段输入异常时,错误展示在错误框底部 按钮触发服务时异常,错误展示在按钮底部 区分不同的类型 错误 成功 警告 提示 调试 简洁易懂的错误信息 在oinone平台中,我们怎么做到友好的错误提示呢?接下来介绍我们的MessageHub,它为自定义错误提示提供无限的可能。 三、如何使用 订阅 import { useMessageHub, ILevel } from "@kunlun/dependencies" const messageHub = useMessageHub('当前视图的唯一标识'); /* 订阅错误信息 */ messageHub.subscribe((errorResult) => { console.log(errorResult) }) /* 订阅成功信息 */ messageHub.subscribe((errorResult) => { console.log(errorResult) }, ILevel.SUCCESS) 图4-2-2-1 订阅的示例代码 销毁 /** * 在适当的时机销毁它 * 如果页面逻辑运行时都不需要销毁,在页面destroyed是一定要销毁,重要!!! */ messageHub.unsubscribe() 图4-2-2-2 销毁的示例代码 四、实战 让我们把3.5.7.5【自定义视图-表单】一文中的自定义表单进行改造,加入我们的messageHub,模拟在表单提交时,后端报错信息在字段下方给予提示。 Step1 (后端)重写PetType的创建函数 重写PetType的创建函数,在创建逻辑中通过MessageHub返回错误信息,返回错误信息的同时要设置paths信息方便前端处理 @Action.Advanced(name = FunctionConstants.create, managed = true) @Action(displayName = "确定", summary = "创建", bindingType = ViewTypeEnum.FORM) @Function(name = FunctionConstants.create) @Function.fun(FunctionConstants.create) public PetType create(PetType data){ List<Object> paths = new ArrayList<>(); paths.add("demo.PetType"); paths.add("kind"); PamirsSession.getMessageHub().msg(new Message().msg("kind error").setPath(paths).setLevel(InformationLevelEnum.ERROR).setErrorType(ErrorTypeEnum.BIZ_ERROR)); List<Object> paths2 = new ArrayList<>(); paths2.add("demo.PetType"); paths2.add("name"); PamirsSession.getMessageHub().msg(new Message().msg("name error").setPath(paths2).setLevel(InformationLevelEnum.ERROR).setErrorType(ErrorTypeEnum.BIZ_ERROR)); // data.create(); return data; } 图4-2-2-3 (后端)重写PetType的创建函数 Step 2 修改PetForm.vue <template> <div class="petFormWrapper"> <form :model="formState" @finish="onFinish"> <a-form-item label="品种种类" id="name" name="kind" :rules="[{ required: true, message: '请输入品种种类!', trigger: 'focus' }]"> <a-input v-model:value="formState.kind" @input="(e) => onNameChange(e, 'kind')" /> <span style="color: red">{{ getServiceError('kind') }}</span> </a-form-item> <a-form-item label="品种名" id="name" name="name" :rules="[{ required: true, message: '请输入品种名!', trigger: 'focus' }]"> <a-input v-model:value="formState.name" @input="(e) => onNameChange(e, 'name')" /> <span style="color: red">{{ getServiceError('name') }}</span> </a-form-item> </form> </div> </template>- <script lang="ts"> import { defineComponent, reactive…

    2024年5月23日
    1.5K00
  • 【工作流】如何添加工作流运行时依赖

    前端 package.json中新增依赖 @kunlun/workflow,版本跟@kunlun/dependencies的填一样 src/main.ts内导入依赖 import 'reflect-metadata'; import { VueOioProvider } from '@kunlun/dependencies'; // START 导入代码放在导入@kunlun/dependencies之后 import '@kunlun/workflow/dist/kunlun-workflow.css'; import '@kunlun/workflow'; // END 导入代码放在VueOioProvider()方法执行前 VueOioProvider({ // TODO }); 后端 父pom新增依赖,下面例子中的版本号仅供参考,请根据当前框架版本正确选择版本 <properties> <pamirs.core.version>4.7.8</pamirs.core.version> <pamirs.workflow.designer.version>4.7.8</pamirs.workflow.designer.version> <pamirs.workbench.version>4.7.8</pamirs.workbench.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>pro.shushi.pamirs.core</groupId> <artifactId>pamirs-core-dependencies</artifactId> <version>${pamirs.core.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <artifactId>pamirs-workflow</artifactId> <version>${pamirs.workflow.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>pro.shushi.pamirs.work.bench</groupId> <artifactId>pamirs-work-bench-core</artifactId> <version>${pamirs.workbench.version}</version> </dependency> <dependency> <groupId>pro.shushi.pamirs.work.bench</groupId> <artifactId>pamirs-work-bench-view</artifactId> <version>${pamirs.workbench.version}</version> </dependency> </dependencies> </dependencyManagement> 2.boot启动工程的pom新增依赖 <dependency> <groupId>pro.shushi.pamirs.core</groupId> <artifactId>pamirs-sql-record-core</artifactId> </dependency> <dependency> <groupId>pro.shushi.pamirs.core</groupId> <artifactId>pamirs-trigger-core</artifactId> </dependency> <dependency> <groupId>pro.shushi.pamirs.core</groupId> <artifactId>pamirs-trigger-bridge-tbschedule</artifactId> </dependency> <dependency> <groupId>pro.shushi.pamirs.core</groupId> <artifactId>pamirs-user-core</artifactId> </dependency> <dependency> <groupId>pro.shushi.pamirs.core</groupId> <artifactId>pamirs-user-view</artifactId> </dependency> <dependency> <groupId>pro.shushi.pamirs.core</groupId> <artifactId>pamirs-auth-core</artifactId> </dependency> <dependency> <groupId>pro.shushi.pamirs.core</groupId> <artifactId>pamirs-business-core</artifactId> </dependency> <dependency> <groupId>pro.shushi.pamirs.core</groupId> <artifactId>pamirs-business-view</artifactId> </dependency> <dependency> <groupId>pro.shushi.pamirs.workflow</groupId> <artifactId>pamirs-workflow-core</artifactId> </dependency> <dependency> <groupId>pro.shushi.pamirs.work.bench</groupId> <artifactId>pamirs-work-bench-core</artifactId> </dependency> <dependency> <groupId>pro.shushi.pamirs.work.bench</groupId> <artifactId>pamirs-work-bench-view</artifactId> </dependency> 3.application.yml配置新增依赖 pamirs: boot: modules: – user – auth – business – sql_record – trigger – workflow 特别注意 工作流模块如果线上部署需要流程设计器能力,可以参考文档流程设计器部署注意事项

    2024年5月30日
    1.5K00
  • 后端环境准备并快速启动

    注意: 部署/启动后端的过程中如果出现问题,请先在 常见问题 中寻找答案。如仍未解决,请及时在群里咨询。 视频教程(点此观看) 一、环境搭建 1. 需要安装的工具 JDK(1.8_221+) Maven IDEA 注意:以上工具需安装在本地开发电脑上,根据实际情况补充所需工具; 已安装请忽略。 2. 安装 JDK(JDK1.8_221+) 检查是否已安装 JDK 在终端中执行以下命令: java -version 如果安装了,会出现版本号。如果没有安装,请选择以下方式下载 JDK: 官网下载(建议下载 JDK 8, installer):Oracle JDK下载 注意:JDK版本必须高于1.8_221+版本。若无法升级,低于这个版本需要覆盖JCE(覆盖JCE:https://www.cnblogs.com/jinloooong/p/10619353.html) 配置环境变量 打开 Windows 环境变量配置页: 此电脑 => 右键属性 => 系统高级设置 => 环境变量 在用户环境变量中新建变量为JAVA_HOME的项,值为JDK安装之后的路径 变量名:JAVA_HOME 变量值:JDK 安装路径 编辑变量为Path的项添加一个值%JAVA_HOME%\bin 在 PowerShell 或 CMD 中验证,输入java -version,输出类似信息为安装配置成功 3. 安装 Maven 检查是否已安装 Maven 在终端中执行: mvn -v 如果安装了,会出现版本号。如果未安装,请下载 Maven: 推荐安装: Maven 3.6.3 下载 下载后解压。 配置 Maven 私服 之前解压的数式提供的部署包中有两个settings.xml文件: 根据 Maven 版本选择对应的 settings.xml 文件: 3.6.x 及以下的版本使用 settings-3.6.3.xml 3.8.x 及以上的版本使用 settings-3.8.x.xml 具体步骤: 将对应的 settings-3.x.x.xml 复制到 Maven 安装目录的 conf 文件夹里面。 备份已有 settings.xml,将已经存在的settings.xml进行备份(即重命名)。 3.然后将 settings-3.x.x.xml 重命名为 settings.xml。 配置环境变量 在用户环境变量中新建变量为M2_HOME的项,值为Maven安装路径 变量名:M2_HOME 变量值:Maven 安装路径 编辑变量为Path的项添加一个值%M2_HOME%\bin 验证安装 在终端执行: mvn –version 出现下列信息,表示成功了: 如果仍然不成功,请检查环境变量配置。 4. 下载安装 IDEA IntelliJ IDEA Community Edition(社区版)即可,该版本免费且完全够用下载方式: 官网下载:IDEA下载链接 二、IDEA 配置 1. 下载 IDEA 插件 有2种方式: 【推荐】根据不同版本下载不同的idea插件 (联系Oinone获取) 插件下载地址:https://guide.oinone.top/zh-cn/DevManual/Tutorials/setup-guide.html#%E4%B8%89%E3%80%81%E5%90%8E%E7%AB%AF%E9%A2%9D%E5%A4%96%E5%B7%A5%E5%85%B7 1、打开 IDEA,依次点击菜单项 File => Settings => Plugins,找到下载的插件包。 2、找到自己前面下载的插件包: 3、idea插件包输入验证码 Oinone企业版需要激活idea插件,设计器版本可不用激活。 输入数式提供的验证码进行验证, 若激活失败(包括无提示)可数式支持人员询问 2. IDEA 配置(Maven 配置,Annotation 配置) 先打开数式提供的部署包中的后端工程 设置 Maven 的 settings.xml: Maven home path:设置为下载的 Maven 路径。 User settings file:设置为 Maven conf 目录下的 settings.xml。 配置 Java Compiler 为 -parameters。 配置 Annotation Processors,勾选 Enable annotation processing。 编译 Maven 拉取包,执行 mvn install,然后再 reload。 3. 项目启动(修改 yml 文件)…

    2024年10月31日
    2.0K00

Leave a Reply

登录后才能评论