深度分页问题优化方案

问题原因

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

相关推荐

  • 【动作】-路由动作跳转后如何主动刷新页面数据

    介绍 当我们使用多tab组件的时候,如果一个viewAction已经打开了一个tab页,再次用该viewAction打开页面的时候,会发现不会根据路由上的业务参数(如详情和编辑页的id参数)主动刷新数据,这个时候可以通过以下方法解决该问题 // 该方法可以在进入新路由页面后刷新数据,推荐将该方法放到工具类 function refreshViewAction(action: any) { const onRefreshTabWithActive = (manager: MultiTabsManager, instance: MultiTabInstance) => { // 进入路由后刷新页面数据 manager.refresh(instance.key); manager.clearOnActive(onRefreshTabWithActive); }; MultiTabsManager.INSTANCE.onActive(onRefreshTabWithActive); executeViewAction(action); } 将原本调用executeViewAction的方法改为refreshViewAction 如果需要扩展executeViewAction的其他入参请自行拓展refreshViewAction的入参

    2024年6月18日
    1.6K00
  • 调试工具在业务场景的使用-前端

    这篇文档主要介绍在业务场景中,使用调试工具解决前端问题的思路。 调试工具的使用见文档:问题排查调试工具使用手册 调试工具的页面内容介绍:Oinone平台可视化调试工具 场景1:页面上的字段被删除 现象:未查询配置字段的数据 在设计页面给类目字段的“选项字段”配置了“速记码(字段名称为fastCode)”在其中 排查路径: 将问题页面url路由中的page改为debug进入页面调试模式,可以看到页面的调试信息 在标签页“页面字段”内的找到问题字段的配置,可以看到optionFields内还是有字段“速记码(字段名称为fastCode)”的但是存储关联关系模型字段配置的options[0].widggets内只有code、name、id字段了,fastCode的元数据未返回 联系后端开发检查模型定义的代码,发现该字段已被注释删除 跟后端同学沟通字段删除后的处理方案 其他相似场景参考 数据字典项出现过删除、重命名 Field字段出现过重命名、配置项发生过更改 Function函数/Action动作出现过删除、重命名 想查看计算公式、条件隐藏、条件禁用、条件只读等表达式的真实值 场景2:动作权限问题排查 现象:页面配置的动作,部分角色登录后无法看到 设计页面是有个“发消息2”的动作 test01用户登录后,发现页面并没有这个动作 排查路径: 将问题页面url路由中的page改为debug进入页面调试模式,可以看到页面的调试信息 在标签页打开“页面动作”,在设计页面的“返回”动作后并没有看到“发消息2”的动作,我们再去权限管理页面查看权限 在权限管理处,查看当前页面的动作权限情况,可以看到“发信息2”的动作确实没有选中 我们将该动作选中后再次刷新运行时的页面,页面动作全部正确展示。

    2024年10月21日
    1.2K00
  • 复杂字段类型的导入导出

    复杂字段类型的导入导出 如果想要导出的字段是该模型关联的对象里的一个字段,则需要在创建模版时使用 “对象.字段” 的方式,并在导出时手动设置该字段 例如PamirsEmployee模型中的company,使用company.name创建值 @Field.many2one @Field.Relation(relationFields = {“companyCode”}, referenceFields = {“code”}) @Field(displayName = “所属公司”) private PamirsCompany company; //定义员工导入导出模版 @Component public class EmployeeTemplate implements ExcelTemplateInit { public static final String TEMPLATE_NAME = "employeeTemplate"; @Override public List<ExcelWorkbookDefinition> generator() { //可以返回多个模版,导出的时候页面上由用户选择导出模版 return Collections.singletonList( ExcelHelper.fixedHeader(PetShop.MODEL_MODEL, TEMPLATE_NAME) .createBlock(TEMPLATE_NAME, PetShop.MODEL_MODEL) .setType(ExcelTemplateTypeEnum.EXPORT) //使用company.name获取PamirsCompany里面的name字段 .addColumn("company.name", "所属公司") .build()); } } //手动设置该字段,如2所示 如果想要导出的字段是非存储字段,由于默认只导出存储在数据库里的字段,非存储的字段需要在导出时手动设置 @Slf4j @Component @Ext(ExcelExportTask.class) public class EmpTemplateExportExtPoint extends DefaultExcelExportFetchDataExtPoint { @Override @ExtPoint.Implement(expression = "context.name==\"" + EmployeeTemplate.TEMPLATE_NAME + "\"") public List<Object> fetchExportData(ExcelExportTask exportTask, ExcelDefinitionContext context) { return super.fetchExportData(exportTask, context); } //重写rawQueryList方法,使用listFieldQuery将非存储字段单独设置 @Override protected List<?> rawQueryList(IWrapper<?> wrapper) { List<PamirsEmployee> pamirsEmployeeProxies = (List<PamirsEmployee>) Models.data().queryListByWrapper(wrapper); if (CollectionUtils.isNotEmpty(pamirsEmployeeProxies)) { new PamirsEmployee().listFieldQuery(pamirsEmployeeProxies, PamirsEmployee::getDepartmentList); } return pamirsEmployeeProxies; } } 如果想要导入的字段存在多个,则可以创建一个代理模型,在代理模型里设置一个字段用来接受该多值字段(在Excel里一个单元格内填写多值字段,每个字段用自定义符号(如:" ; ")进行分割),在创建模版时使用该代理类的模版,在导入导出的时候再根据 “;” 截取 @Model.model(PamirsEmployeeProxy.MODEL_MODEL) @Model(displayName = "员工导出代理") @Model.Advanced(type = ModelTypeEnum.PROXY) public class PamirsEmployeeProxy extends PamirsEmployee { private static final long serialVersionUID = -6582160484690807999L; public static final String MODEL_MODEL = "business.PamirsEmployeeProxy"; @Field.String @Field(displayName = "部门编码列表") private String departmentCodeList; } 创建模版时创建代理模型的字段 .addColumn("departmentCodeList", "部门编码列表") 导入:新建一个类,用来作为导入的扩展点,继承AbstractExcelImportDataExtPointImpl @Component @Ext(ExcelImportTask.class) @Slf4j public class EmpTemplateImportExtPoint extends AbstractExcelImportDataExtPointImpl<PamirsEmployeeProxy> { //必须加这个方法,它使用EmployeeTemplate.TEMPLATE_NAME来指定导入模版 @Override @ExtPoint.Implement(expression = "importContext.definitionContext.name==\"" + EmployeeTemplate.TEMPLATE_NAME + "\"") public Boolean importData(ExcelImportContext importContext, PamirsEmployeeProxy data) { //TODO 根据逻辑校验数据 String departmentCodeList = data.getDepartmentCodeList();…

    2024年7月1日
    1.2K00
  • 资源

    翻译应用是管理翻译规则的应用,以模型为基础、维护字段的翻译值,支持导入、导出 1. 操作步骤 Step1:导出所有翻译项; Step2:线下翻译; Step3:导入翻译项; Step4:刷新远程资源; Step5:页面右上角可切换语言,查看翻译效果。 2. 新增翻译 翻译是具体到模型字段,其中需要区分出是否字典; 源语言、目标语言,是在资源中维护的语言,可在资源中维护需要翻译的语言; 翻译项则是模型字段,默认翻译项为激活状态,关闭后维护的翻译项无效。 3. 导出、导入 不勾选导出:导出所有需要翻译的翻译项,包括模块、字段,源术语、翻译值等,其中如果已经翻译过的内容,会体现在翻译值中; 勾选导出:导出勾选模型的翻译项。 导入:导入翻译项,平台会根据模型拆分为多条数据。 4. 刷新远程资源 导入翻译项后,点击“刷新远程资源”按钮。 5. 查看翻译内容 页面右上角切换语言,查看翻译效果。

    2024年6月20日
    1.3K00
  • 3.0.1版本更新说明-2022.06.28

    版本号:3.0.1发布日期:2022.06.28更新要点:PAAS更新:优化系统结构,提升性能和稳定性,删除无用域名h5.oinone.top。页面设计器更新:修复数据丢失和未绑定模型问题,优化用户体验,提高应用可靠性。全员营销更新:优化模板匹配规则,提高视频合成成功率,提升营销效果和用户满意度。 1 发布概要 1.1 paas 发布内容: 删除h5.oinone.top 1.2 页面设计器 修复表单内嵌表格,自带viewAction在应用重启后元数据丢失的问题 修复页面发布后,未绑定模型的问题 由于3.0.1版本后端代码提前上线,3.0.2隐藏布局容器,置空设计页面协议版本号。待前端发布后再恢复 1.3 全员营销 优化模板匹配规则,提高视频合成成功率 2. 版本信息 <!–pamirs底层包–> <pamirs.middleware.version>3.0.1</pamirs.middleware.version> <pamirs.boot.version>3.0.1</pamirs.boot.version> <pamirs.core.version>3.0.1</pamirs.core.version> <pamirs.tenant.version>3.0.1</pamirs.tenant.version> <pamirs.lowcode.version>3.0.1</pamirs.lowcode.version> <pamirs.distribution.version>3.0.1</pamirs.distribution.version> <!–设计器包–> <pamirs.designer.version>3.0.1</pamirs.designer.version> <pamirs.workflow.designer.version>3.0.1</pamirs.workflow.designer.version> <pamirs.model.designer.version>3.0.1</pamirs.model.designer.version> <pamirs.logic.designer.version>3.0.1</pamirs.logic.designer.version> <pamirs.ui.designer.version>3.0.2</pamirs.ui.designer.version> <pamirs.data.designer.version>3.0.1</pamirs.data.designer.version> <pamirs.data.visualization.version>3.0.1</pamirs.data.visualization.version> <!–官网用户包–> <pamirs.welcome.version>3.0.1</pamirs.welcome.version> <!–全员营销–> <pamirs.gemini.version>3.0.2</pamirs.gemini.version> <!–pass包–> <pamirs.paas.version>3.0.1</pamirs.paas.version> 如果您有任何问题、建议或反馈,请随时联系我们。为了获得最佳体验,请确保您始终使用最新版本。我们将继续努力改进产品,提供更好的服务。谢谢支持!

    2022年6月28日
    1.6K00

Leave a Reply

Please Login to Comment