深度分页问题优化方案

问题原因

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

相关推荐

  • Oinone 如何接入乾坤微前端

    开发过程中,我们通常很难对一个已经存在的系统做全量的技术栈升级或重构,这时候我们需要引入微前端作为渐进式重构的手段和策略。为了满足将Oinone无缝接入现有项目,能在现有项目和Oinone之间路由、嵌套、通信等的需求,现整理出了Oinone接入乾坤的模版工程——工程压缩包地址 模版工程启动 工程结构目录介绍 最外层micro-front-end用pnpm工作区来管理多工程仓库,维护统一的安装、运行、清除、构建等的脚本。micro-main是主应用,micro-son是子应用,模拟重构工作量巨大的老应用,ss-front-modules是Oinone应用。micro-front-end/│── packages/│ ├── micro-main/│ │ ├── package.json│ ├── micro-son/│ │ ├── package.json│ ├── ss-front-modules/│ │ ├── packages/│ │ │ ├── ss-admin-widget/│ │ │ ├── ss-boot/│ │ │ ├── ss-oinone/│ │ │ ├── ss-project/│ │ ├── package.json│── package.json 模版工程安装、运行 1. 安装 在micro-front-end目录下 pnpm install 2. 运行 在micro-front-end目录下 pnpm run dev,这里应当能看到启动了三个服务(端口8888~8890),其中http://localhost:8888/是主应用。 3. 效果 进入 http://localhost:8888/主应用 ,可以路由到Oinone应用看效果 接入步骤分析 1. 主应用搭建 微应用注册配置 配置了一个oinone的子应用,name是ss-boot。 export const SUB_APP_CONFIG = { subApps: [ { name: 'micro-son', // 子应用名称,跟package.json一致 entry: '//localhost:8889', // 子应用入口,本地环境下指定端口 container: '#micro-son', // 挂载子应用的dom activeRule: '/app/micro-son', // 路由匹配规则 props: {}, // 主应用与子应用通信传值 sandbox: { strictStyleIsolation: false, // 关闭严格样式隔离 experimentalStyleIsolation: false // 关闭实验性样式隔离 } }, { name: 'ss-boot', // 子应用名称,跟package.json一致 entry: '//localhost:8890', // 子应用入口,本地环境下指定端口 container: '#app-oinone', // 挂载子应用的dom activeRule: '/app/ss-boot', // 路由匹配规则 props: {}, // 主应用与子应用通信传值 sandbox: { strictStyleIsolation: false, // 关闭严格样式隔离 experimentalStyleIsolation: false // 关闭实验性样式隔离 } } ] }; main.ts 执行注册逻辑 import { registerMicroApps } from "qiankun"; function registerApps() { try { // 调用乾坤注册微应用方法,subApps 就是上面的配置 registerMicroApps(subApps, { beforeLoad: [ (app) => { console.log("before load", app); return Promise.resolve(); }, ], beforeMount: [ (app) => { console.log("before mount", app); return Promise.resolve(); }, ], afterUnmount:…

    2025年3月27日
    91900
  • 正式版发布:Oinone 5.3.0 版本 新增微流设计器,邀您体验

    版本号: 5.3.0 版本发布日期:2024.12.05更新要点:新增微流设计器 5.3.0 版本 升级说明及步骤(已升级为5.0.0版本忽略) 5.3.x版本以后无法通过4.7.8版本进行升级,请先升级到5.2.x版本进行权限迁移后再升级至5.3.x版本 升级内容(5.3.0) 设计器yaml配置 pamirs: boot: modules: – microflow_designer 请尽可能保证业务工程前后端服务以及设计器同步升级前端服务仅需重新执行npm run clean && npm install即可自动升级到最新版本 后端版本包信息 Oinone平台部署及依赖说明(v5.0) 未使用到的版本号请忽略,按项目中使用到的进行替换。 <!– 平台基础 –> <oinone.version>5.3.0</oinone.version> <!– 设计器 –> <pamirs.workflow.designer.version>5.3.0</pamirs.workflow.designer.version> <pamirs.model.designer.version>5.3.0</pamirs.model.designer.version> <pamirs.ui.designer.version>5.3.0</pamirs.ui.designer.version> <pamirs.data.designer.version>5.3.0</pamirs.data.designer.version> <pamirs.dataflow.designer.version>5.3.0</pamirs.dataflow.designer.version> <pamirs.eip.designer.version>5.3.0</pamirs.eip.designer.version> <pamirs.microflow.designer.version>5.3.0</pamirs.microflow.designer.version> <dependencyManagement> <dependencies> <dependency> <groupId>pro.shushi</groupId> <artifactId>oinone-bom</artifactId> <version>${oinone.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> oinone-bom详细版本信息 <!– 平台基础 –> <pamirs.middleware.version>5.2.3</pamirs.middleware.version> <pamirs.k2.version>5.3.0</pamirs.k2.version> <pamirs.framework.version>5.3.0</pamirs.framework.version> <pamirs.boot.version>5.3.0</pamirs.boot.version> <pamirs.distribution.version>5.3.0</pamirs.distribution.version> <!– 平台功能 –> <pamirs.metadata.manager>5.3.0</pamirs.metadata.manager> <pamirs.designer.metadata.version>5.3.0</pamirs.designer.metadata.version> <pamirs.core.version>5.3.0</pamirs.core.version> <pamirs.workflow.version>5.3.0</pamirs.workflow.version> <pamirs.workbench.version>5.3.0</pamirs.workbench.version> <pamirs.data.visualization.version>5.3.0</pamirs.data.visualization.version> <!– 设计器 –> <pamirs.designer.common.version>5.3.0</pamirs.designer.common.version> <pamirs.flow.designer.base.version>5.3.0</pamirs.flow.designer.base.version> 前端版本包信息 { "@kunlun/vue-dependencies": "5.3.0", "@kunlun/vue-ui-antd": "5.3.0", "@kunlun/vue-ui-el": "5.3.0", "@kunlun/vue-mobile-dependencies": "5.3.0", "@kunlun/vue-ui-mobile-vant": "5.3.0", "@kunlun/mobile-workbench": "5.3.0", "@kunlun/data-designer-open-pc": "5.3.0", "@kunlun/data-designer-open-mobile": "5.3.0" } 前端详细版本信息 可通过node_modules/@kunlun查看 { "@kunlun/cache": "5.3.0", "@kunlun/dsl": "5.3.0", "@kunlun/event": "5.3.0", "@kunlun/expression": "5.3.0", "@kunlun/meta": "5.3.0", "@kunlun/request": "5.3.0", "@kunlun/router": "5.3.0", "@kunlun/service": "5.3.0", "@kunlun/shared": "5.3.0", "@kunlun/spi": "5.3.0", "@kunlun/state": "5.3.0", "@kunlun/theme": "5.3.0", "@kunlun/engine": "5.3.0", "@kunlun/vue-admin-base": "5.3.0", "@kunlun/vue-admin-layout": "5.3.0", "@kunlun/vue-dependencies": "5.3.0", "@kunlun/vue-router": "5.3.0", "@kunlun/vue-ui": "5.3.0", "@kunlun/vue-ui-antd": "5.3.0", "@kunlun/vue-ui-common": "5.3.0", "@kunlun/vue-ui-el": "5.3.0", "@kunlun/vue-widget": "5.3.0", "@kunlun/vue-expression": "5.2.0", "@kunlun/vue-mobile-base": "5.3.0", "@kunlun/vue-mobile-dependencies": "5.3.0", "@kunlun/vue-ui-mobile-vant": "5.3.0", "@kunlun/mobile-workbench": "5.3.0", "@kunlun/data-designer-core": "5.3.0", "@kunlun/data-designer-core-mobile": "5.3.0", "@kunlun/data-designer-core-pc": "5.3.0", "@kunlun/data-designer-open-mobile": "5.3.0", "@kunlun/data-designer-open-pc": "5.3.0" } 镜像说明 所有镜像均使用docker manifest支持amd64和arm64架构。如镜像拉取过慢,可在对应镜像Tag添加-amd64、-arm64后缀获取单一架构镜像。 docker pull harbor.oinone.top/oinone/oinone-designer-full-v5.3:5.3.0-amd64 docker pull harbor.oinone.top/oinone/oinone-designer-full-v5.3:5.3.0-arm64 镜像拉取 镜像或JAR版本:5.3.0 体验镜像:(所有中间件及前后端服务,包含全部设计器) docker pull harbor.oinone.top/oinone/oinone-designer-full-v5.3:5.3.0 部署镜像:(包含前后端服务,包含全部设计器) docker pull harbor.oinone.top/oinone/oinone-designer-mini-v5.3:5.3.0 流程设计器镜像:(包含前后端服务,仅包含流程设计器) docker pull…

    2024年12月5日
    1.1K00
  • 前端页面嵌套

    我们可能会遇到这些需求,如:页面中的一对多字段不是下拉框,而是另一个模型的表单组;页面中的步骤条表单,每一步的表单都需要界面设计器设计,同时这些表单可能属于不同模型。这时候我们就可以采取页面嵌套的方式,在当前页面中,动态创建一个界面设计器设计的子页面。以一对多字段,动态创建表单子页面举例,以下是代码实现和原理分析。 代码实现 AddSubformWidget 动态添加表单 ts 组件 import { ModelFieldType, ViewType, SPI, BaseFieldWidget, Widget, FormO2MFieldWidget, ActiveRecord, CallChaining, createRuntimeContextByView, queryViewDslByModelAndName, uniqueKeyGenerator } from '@oinone/kunlun-dependencies'; import { MyMetadataViewWidget } from './MyMetadataViewWidget'; import { watch } from 'vue'; import AddSubform from './AddSubform.vue'; @SPI.ClassFactory( BaseFieldWidget.Token({ viewType: ViewType.Form, ttype: ModelFieldType.OneToMany, widget: 'AddSubform' }) ) export class AddSubformWidget extends FormO2MFieldWidget { public initialize(props) { super.initialize(props); this.setComponent(AddSubform); return this; } @Widget.Reactive() public myMetadataViewWidget: MyMetadataViewWidget[] = []; @Widget.Reactive() public myMetadataViewWidgetKeys: string[] = []; @Widget.Reactive() public myMetadataViewWidgetLength = 0; // region 子视图配置 public get subviewModel() { return this.getDsl().subviewModel || 'clm.contractcenter.ContractSignatory'; } public get subviewName() { return this.getDsl().subviewName || '签署方_FORM_uiViewa9c114903e104800b15e8f3749656b64'; } // region 添加子视图块 // 按钮添加点击事件 @Widget.Method() public async onAddSubviewBlock() { const resView = await queryViewDslByModelAndName(this.subviewModel, this.subviewName); this.createDynamicSubviewWidget(resView); } // 创建子视图块 public async createDynamicSubviewWidget(view, activeRecord: ActiveRecord = {}) { if (view) { // 根据视图构建上下文 const runtimeContext = createRuntimeContextByView( { type: ViewType.Form, model: view.model, modelName: view.modelDefinition.name, module: view.modelDefinition.module, moduleName: view.modelDefinition.moduleName, name: view.name, dsl: view.template }, true, uniqueKeyGenerator(), this.currentHandle ); // 取得上下文唯一标识 const runtimeContextHandle = runtimeContext.handle; const slotKey = `Form_${uniqueKeyGenerator()}`; // 创建子视图组件 const widget = this.createWidget(new MyMetadataViewWidget(runtimeContextHandle), slotKey, // 插槽名 { metadataHandle: runtimeContextHandle,…

    2025年7月21日
    1.3K00
  • 自定义的复杂字段配置透出字段

    学习这篇文章之前,需要先学会使用在界面设计器自定义一个前端组件,如果您还不会,可以先看这篇文章 默认情况下,当开前端发人员自定义了一个复杂字段,比如M2O、O2M、M2M的字段,那么Graphql查询的时候,只会查询id跟name这两个字段,如果还想查询字段的字段,那么可以通过配置化的方式来处理 1: 在界面设计器的组件区域中新增对应的字段 2: 设计元件,在模型区域中搜索选项字段列表,拖到设计区域,然后保存 3: 去对应的设计页面,刷新下页面,选中对应的字段,可以看到右侧有选项字段列表4: 输入期望Graphql查询字段,保存发布

    2023年11月9日
    2.5K00
  • 前端6.2.x升级指南

    升级背景 从 6.2.x 版本开始,平台底层核心代码已全面开源(设计器相关代码除外),本次升级涉及包名变更和配置调整,以下是详细的升级步骤 1. 更新 .npmrc 配置 修改当前项目根目录 .npmrc 文件,内容如下: registry=https://registry.npmmirror.com/ @oinone:registry=http://nexus.shushi.pro/repository/kunlun/ @kunlun:registry=http://nexus.shushi.pro/repository/kunlun/ shamefully-hoist=true legacy-peer-deps=true link-workspace-packages = true prefer-workspace-packages = true recursive-install = true lockfile=true 2. 包名变更 以前的包是 @kunlun/xxxx,现在的包名是@oinone/kunlun开头,所以需要全部替换修改。 旧包名 新包名 @kunlun/dependencies @oinone/kunlun-dependencies @kunlun/vue-ui-antd @oinone/kunlun-vue-ui-antd 3. 升级依赖版本 修改所有 package.json 中更新所有平台相关依赖: – "@kunlun/dependencies": "~5.7.0" + "@oinone/kunlun-dependencies": "~6.2.0" boot工程的package.json新增devDependencies依赖 "devDependencies": { "@types/lodash": "4.14.182", "@types/lodash-es": "4.17.6", ….. } 4. 更新代码引用 全局搜索并替换代码中的所有 @kunlun/ 为 @oinone/kunlun- 完整的 main.ts import 'ant-design-vue/dist/antd.min.css'; import 'element-plus/dist/index.css'; import '@oinone/kunlun-vue-ui-antd/dist/oinone-kunlun-vue-ui-antd.css'; import '@oinone/kunlun-vue-ui-el/dist/oinone-kunlun-vue-ui-el.css'; import '@oinone/kunlun-designer-common/dist/oinone-kunlun-designer-common.css'; import '@oinone/kunlun-model-designer/dist/oinone-kunlun-model-designer.css'; import '@oinone/kunlun-workflow-designer/dist/oinone-kunlun-workflow-designer.css'; import '@oinone/kunlun-workflow/dist/oinone-kunlun-workflow.css'; import '@oinone/kunlun-data-designer/dist/oinone-kunlun-data-designer.css'; import '@oinone/kunlun-microflow-designer/dist/oinone-kunlun-microflow-designer.css'; import 'reflect-metadata'; import ElementPlus from 'element-plus'; import { App } from 'vue'; import { VueOioProvider, RuntimeContextManager } from '@oinone/kunlun-dependencies'; // 设计器 import '@oinone/kunlun-ui-designer-dependencies'; import '@oinone/kunlun-print-designer-dependencies'; import '@oinone/kunlun-workflow'; import '@oinone/kunlun-workflow-designer'; import '@oinone/kunlun-model-designer'; import '@oinone/kunlun-data-designer'; import '@oinone/kunlun-data-designer-open-pc'; import '@oinone/kunlun-eip-dependencies'; import '@oinone/kunlun-ai-dependencies'; import '@oinone/kunlun-microflow-designer'; import '@oinone/kunlun-designer-common-ee'; // 下面三个依赖是当前工程的包,请根据实际场景修改 import '@ss/oinone'; import '@ss/admin-widget'; import '@ss/project'; VueOioProvider( { browser: { title: 'Oinone – 构你想象!', favicon: 'https://pamirs.oss-cn-hangzhou.aliyuncs.com/pamirs/image/default_favicon.ico' } }, [ () => { /// 获取当前vue实例 const app = RuntimeContextManager.createOrReplace().frameworkInstance as App; } ] ); 当配置全部修改完成后,重写安装依赖 # 清理旧依赖 pnpm clean # 安装新依赖 pnpm install

    2025年6月17日
    79200

Leave a Reply

Please Login to Comment