深度分页问题优化方案

问题原因

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

相关推荐

  • 如何使用GQL工具正确发起请求

    简介 本文将讲解一下如何正确发起GQL请求和GQL工具使用过程中的常见问题。 参数介绍 请求url和请求方法在浏览器的请求标头里面可以查到,保持一致就可以向服务正常发送请求,但还缺少请求体确定请求哪个接口。 每个请求都包括两部分内容:1. Query 2. Variables右键Query和Variables复制值直接拷贝到工具中就可以正常请求了。 注意:如果使用admin账号登录,请求的时候可以不携带Variables参数,因为admin没有权限控制,如果使用其他用户,就必须携带Variables参数,否则会被权限拦截。

    2024年10月25日
    2.3K00
  • 5.0.0版本bugfix:修复流程日志循环节点超时,请升级对应版本

    版本号: 5.0.2 版本发布日期:2024.06.03更新要点:修复流程日志-在存在循环节点的日志超时 5.0.2 版本 升级说明及步骤(已升级为5.0.0版本忽略) 此版本与4.7.8版本的兼容方案如下,请严格参照升级说明及步骤进行1、【重要】升级前备份base库和用户权限模块所在的库 2、【重要】升级过程执行SQL严格按照升级文档中的步骤执行。特别注意:部分SQL是要求【发布前执行】,部分SQL是要求【发布后执行】 5.0.0升级详细说明及步骤 升级内容(5.0.0) 修复流程日志-在存在循环节点的日志超时 Excel导入导出模板提供使用接口方式进行翻译 请尽可能保证设计器和业务工程同步升级对应版本 版本包信息 未使用到的版本号请忽略,按项目中使用到的进行替换 <!– 平台基础 –> <pamirs.middleware.version>5.0.0</pamirs.middleware.version> <pamirs.k2.version>5.0.1</pamirs.k2.version> <pamirs.framework.version>5.0.2</pamirs.framework.version> <pamirs.boot.version>5.0.1</pamirs.boot.version> <pamirs.distribution.version>5.0.1</pamirs.distribution.version> <!– 平台功能 –> <pamirs.metadata.manager>5.0.0</pamirs.metadata.manager> <pamirs.core.version>5.0.5</pamirs.core.version> <pamirs.workflow.version>5.0.2</pamirs.workflow.version> <pamirs.workbench.version>5.0.1</pamirs.workbench.version> <pamirs.data.visualization.version>5.0.1</pamirs.data.visualization.version> <!– 设计器 –> <pamirs.designer.common.version>5.0.1</pamirs.designer.common.version> <pamirs.flow.designer.base.version>5.0.1</pamirs.flow.designer.base.version> <pamirs.workflow.designer.version>5.0.1</pamirs.workflow.designer.version> <pamirs.model.designer.version>5.0.1</pamirs.model.designer.version> <pamirs.ui.designer.version>5.0.1</pamirs.ui.designer.version> <pamirs.data.designer.version>5.0.1</pamirs.data.designer.version> <pamirs.dataflow.designer.version>5.0.2</pamirs.dataflow.designer.version> <pamirs.eip.designer.version>5.0.1</pamirs.eip.designer.version> 注意镜像名称变化 镜像说明 所有镜像均使用docker manifest支持amd64和arm64架构。如镜像拉取过慢,可在对应镜像Tag添加-amd64、-arm64后缀获取单一架构镜像。 docker pull harbor.oinone.top/oinone/oinone-designer-full-v5.0:5.0.3.3-amd64 docker pull harbor.oinone.top/oinone/oinone-designer-full-v5.0:5.0.3.3-arm64 镜像拉取 体验镜像:(所有中间件及前后端服务,包含全部设计器) docker pull harbor.oinone.top/oinone/oinone-designer-full-v5.0:5.0.3.3 docker pull harbor.oinone.top/oinone/oinone-designer-full-v5.0:latest 部署镜像:(包含前后端服务,包含全部设计器) docker pull harbor.oinone.top/oinone/oinone-designer-mini-v5.0:5.0.3.3 docker pull harbor.oinone.top/oinone/oinone-designer-mini-v5.0:latest 流程设计器镜像:(包含前后端服务,仅包含流程设计器) docker pull harbor.oinone.top/oinone/workflow-designer-v5.0:5.0.3.3 docker pull harbor.oinone.top/oinone/workflow-designer-v5.0:latest 流程设计器镜像:(包含前后端服务,仅包含流程设计器,非外部库镜像) docker pull harbor.oinone.top/oinone/workflow-designer-standard-v5.0:5.0.3.3 docker pull harbor.oinone.top/oinone/workflow-designer-standard-v5.0:latest 后端镜像:(仅包含后端服务,包含全部设计器) docker pull harbor.oinone.top/oinone/designer-backend-v5.0:5.0.3.3 docker pull harbor.oinone.top/oinone/designer-backend-v5.0:latest 前端镜像:(仅包含前端服务,包含全部设计器) docker pull harbor.oinone.top/oinone/designer-frontend-v5.0:5.0.3 docker pull harbor.oinone.top/oinone/designer-frontend-v5.0:latest 独立部署流程设计器JAR:(包含前后端服务,仅包含流程设计器)pamirs-workflow-designer-boot-v5.0-5.0.3.3.jarpamirs-workflow-designer-boot-v5.0-latest.jar 后端无代码设计器Jar包启动方法 如果您有任何问题、建议或反馈,请随时联系我们。为了获得最佳体验,请及时更新至最新版本。我们将继续努力改进产品,提供更好的服务。谢谢!

    2024年6月3日
    1.9K00
  • 4.5.2 研发辅助之SQL优化

    Oinone体系中是不需要针对模型写SQL的,默认提供了通用的数据管理器。在带来便利的情况下,也导致传统的sql审查就没办法开展。但是我们可以以技术的手段收集慢SQL和限制问题SQL执行。 慢SQL搜集目的:去发现非原则性问题的慢SQL,并进行整改 限制问题SQL执行:对应一些不规范的SQL系统上直接做限制,如果有特殊情况手动放开 一、发现慢SQL 这个功能并没有直接加入到oinone的版本中,需要业务自行写插件,插件代码如下。大家可以根据实际情况进行改造比如: 堆栈入口,例子中只是放了pamirs,可以根据实际情况改成业务包路径 对慢SQL的定义是5s还是3s,根据实际情况变 package pro.shushi.pamirs.demo.core.plugin; import org.apache.ibatis.executor.Executor; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.plugin.*; import org.apache.ibatis.session.ResultHandler; import org.apache.ibatis.session.RowBounds; import org.springframework.stereotype.Component; import pro.shushi.pamirs.meta.annotation.fun.extern.Slf4j; @Intercepts({ @Signature(type = Executor.class,method = "query",args = {MappedStatement.class,Object.class, RowBounds.class, ResultHandler.class}) }) @Component @Slf4j public class SlowSQLAnalysisInterceptor implements Interceptor { @Override public Object intercept(Invocation invocation) throws Throwable { long start = System.currentTimeMillis(); Object result = invocation.proceed(); long end = System.currentTimeMillis(); if (end – start > 10000) {//大于10秒 try { StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace(); StringBuffer slowLog = new StringBuffer(); slowLog.append(System.lineSeparator()); for (StackTraceElement element : stackTraceElements) { if (element.getClassName().indexOf("pamirs") > 0) { slowLog.append(element.getClassName()).append(":").append(element.getMethodName()).append(":").append(element.getLineNumber()).append(System.lineSeparator()); } } Object parameter = null; if (invocation.getArgs().length > 1) { parameter = invocation.getArgs()[1]; } MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0]; BoundSql boundSql = mappedStatement.getBoundSql(parameter); Configuration configuration = mappedStatement.getConfiguration(); String originalSql = showSql(configuration, boundSql); originalSql = originalSql.replaceAll("\'", "").replace("\"", ""); log.warn("检测到的慢SQL为:" + originalSql); log.warn("业务慢SQL入口为:" + slowLog.toString()); } catch (Throwable e1) { //忽略 } } return result; } public String showSql(Configuration configuration, BoundSql boundSql) { Object parameterObject = boundSql.getParameterObject(); List<ParameterMapping> parameterMappings = boundSql.getParameterMappings(); String sql = boundSql.getSql().replaceAll("[\\s]+", " "); if (parameterMappings.size() > 0 && parameterObject != null) { TypeHandlerRegistry typeHandlerRegistry…

    Oinone 7天入门到精通 2024年5月23日
    2.0K00
  • O2M、M2O、M2M关系字段配置问题以及问题排查路径

    M2O关系字段 配置示例: @Field(displayName = “教师关联学生”) @Field.many2one @Field.Relation(relationFields = {“studentName”}, referenceFields = {“name”}) private Student students; 解析: 在这个多对一关系中,studentName为本模型的字段,name为Student的字段,这个多对一关系通过这两个字段关联起来。 在保存该关联关系时,会将name的值带到studentName里并保存在当前模型中(many) studentName字段必须是存储字段,因为在查询many的数据的时候是通过这个字段进行查询的。 name必须在关系模型即Student里面定义(one),studentName在本模型里面定义不定义都可以,如果没有的话会在本模型中创建该字段。 常见问题: 启动报错:根据报错内容进行相应修改 保存报错:Duplicate entry '******' for key 'PRIMARY',报这个错是因为studentName是唯一键,在将相同name的值赋值给studentName时导致唯一键冲突。其他关系也会有此情况。 O2M关系字段 配置示例: @Field(displayName = "教师关联宠物") @Field.one2many @Field.Relation(relationFields = {"id"}, referenceFields = {"teacherId"}) private List<PetShop> studentsCode; 解析: 在这个一对多关系中,id为本模型的字段,teacherId为PetShop的字段,这个一对多关系通过这两个字段关联起来。 在保存该关联关系时,会将id的值带到teacherId里并保存在PetShop模型中(many) id必须在本模型中定义(one), teacherId在PetShop模型里面定义不定义都可以,如果没有的话会在PetShop模型中创建该字段。 常见问题: 启动报错:根据报错内容进行相应修改 保存报错:请先保存关联关系模型:如果 id 为自定义字段 与 PetShop进行关联,那么保存关联关系时必须给id 赋值,不然会报错 M2M关系字段 配置示例1: @Field.many2many(through = OrderRelLogistics.MODEL_MODEL, relationFields = {"parentOrderId"}, referenceFields = {"logisticsBillId"}) @Field.Relation(relationFields = {"id"}, referenceFields = {"id"}) @Field(displayName = "物流单") private List<LogisticsBill> logisticsBillList; 解析: 在这个多对多关系中,id(左)为本模型的字段,id(右)为PetShop的字段。OrderRelLogistics.MODEL_MODEL为中间表,在保存关联关系时中间表会维护双方的关系字段,id(左)的值写到中间表的parentOrderId字段,id(右)的值写到中间表的logisticsBillId字段。 常见问题: 保存报错,请先保存关联关系模型:如果id(左)为在本模型自定义的字段,则需要在保存关联关系的时候的时候将该自定义赋值,这样才能正确保存关联关系。 配置示例2: 新增TalentTypeEnum @Dict(dictionary = TalentTypeEnum.DICTIONARY,displayName = “达人类型”) public class TalentTypeEnum extends BaseEnum { public static final String DICTIONARY =”top.TalentTypeEnum”; public final static TalentTypeEnum DOG =create(“DOG”,1,”狗达人”,”狗达人”); public final static TalentTypeEnum CAT =create(“CAT”,2,”猫达人”,”猫达人”); } 中间表定义 @Model.model(PetItemRelPetTalent.MODEL_MODEL) @Model(displayName = “中间表”, summary = “中间表”) public class PetItemRelPetTalent extends BaseRelation { public static final String MODEL_MODEL = “top.PetItemRelPetTalent”; @Field.String @Field(displayName = “商店ID”) private String petItemId; @Field.String @Field(displayName = “宠物ID”) private String petTalentId; @Field.String @Field(displayName = “宠物类型”) private TalentTypeEnum talentType; } 关系字段定义(关联关系中,使用”##“包括定义常量,这里定义常量"test") @Field(displayName = “推荐达人”) @Field.many2many( through = PetItemRelPetTalent.MODEL_MODEL, relationFields = {“petItemId”}, referenceFields = {“petTalentId”,”talentType”} ) @Field.Relation(relationFields = {“id”}, referenceFields = {“id”, “#2#”})…

    2024年8月9日
    2.4K00
  • 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.3K00

Leave a Reply

Please Login to Comment