深度分页问题优化方案

问题原因

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

相关推荐

  • 左树右表页面,点击表格的新建按钮,获取选中的树节点

    左树右表页面,点击表格的新建按钮,获取选中的树节点 通过自定义action的方式来实现 新建一个action文件TreeActionWidget.ts import { ActionType, ActionWidget, SPI, ViewActionTarget, RouterViewActionWidget } from '@kunlun/dependencies'; import { OioNotification } from '@kunlun/vue-ui-antd'; @SPI.ClassFactory( ActionWidget.Token({ actionType: [ActionType.View], target: [ViewActionTarget.Router], name: 'uiView0000000000079503' // action对应的name }) ) export class TreeActionWidget extends RouterViewActionWidget { protected async clickAction() { const context = this.rootRuntimeContext.view.context || {}; const activeTreeContext = context.activeTreeContext || null; if (!activeTreeContext) { // 没有选中左侧树 OioNotification.error('', '请选择左侧节点!'); } else { // 选中的时候 (this.action as any).context = activeTreeContext; // 执行原先的action逻辑 super.clickAction(); } } }

    2023年11月1日
    1.4K00
  • 4.7.8.15版本升级说明-20240605

    版本号: 4.7.8.15 版本发布日期:2024.06.05更新要点:修复在配置BasePath时无法正常下载导入模板问题 4.7.8.15 版本 升级内容 修复在配置BasePath时无法正常下载导入模板问题 修复界面设计器无法正常创建他表字段的问题 修复界面设计器无法正常创建范围组件的问题 版本包信息 未使用到的版本号请忽略,按项目中使用到的进行替换 <!– 平台基础 –> <pamirs.middleware.version>4.7.8.3</pamirs.middleware.version> <pamirs.k2.version>4.7.8.5</pamirs.k2.version> <pamirs.framework.version>4.7.8.11</pamirs.framework.version> <pamirs.boot.version>4.7.8.8</pamirs.boot.version> <pamirs.distribution.version>4.7.8.3</pamirs.distribution.version> <!– 平台功能 –> <pamirs.metadata.manager>4.7.8</pamirs.metadata.manager> <pamirs.core.version>4.7.8.10</pamirs.core.version> <pamirs.workflow.version>4.7.8.9</pamirs.workflow.version> <pamirs.workbench.version>4.7.8</pamirs.workbench.version> <pamirs.data.visualization.version>4.7.8</pamirs.data.visualization.version> <!– 设计器 –> <pamirs.designer.common.version>4.7.8</pamirs.designer.common.version> <pamirs.flow.designer.base.version>4.7.8.1</pamirs.flow.designer.base.version> <pamirs.workflow.designer.version>4.7.8</pamirs.workflow.designer.version> <pamirs.model.designer.version>4.7.8</pamirs.model.designer.version> <pamirs.ui.designer.version>4.7.8.8</pamirs.ui.designer.version> <pamirs.data.designer.version>4.7.8</pamirs.data.designer.version> <pamirs.dataflow.designer.version>4.7.8.1</pamirs.dataflow.designer.version> <pamirs.eip.designer.version>4.7.8.1</pamirs.eip.designer.version> 注意镜像名称变化 体验镜像:(所有中间件及前后端服务,包含全部设计器)docker pull harbor.oinone.top/oinone/oinone-designer-full-v4.8:4.8.6.2 部署镜像:(包含前后端服务,包含全部设计器)docker pull harbor.oinone.top/oinone/oinone-designer-mini-v4.8:4.8.6.2 流程设计器镜像:(包含前后端服务,仅包含流程设计器)docker pull harbor.oinone.top/oinone/workflow-designer-v4.8:4.8.6.2 流程设计器镜像:(包含前后端服务,仅包含流程设计器,非外部库镜像)docker pull harbor.oinone.top/oinone/workflow-designer-standard-v4.8:4.8.6.2 独立部署流程设计器JAR:(包含前后端服务,仅包含流程设计器)pamirs-workflow-designer-boot-4.8.6.2.jar 后端无代码设计器Jar包启动方法 如果您有任何问题、建议或反馈,请随时联系我们。为了获得最佳体验,请及时更新至最新版本。我们将继续努力改进产品,提供更好的服务。谢谢!

    2024年6月5日
    1.4K00
  • 总体结构设计示例

    1.项目总体架构 Oinone总体工程架构 Oinone总体项目分层 以常见的B2C和全渠道订单OMS为例分层说明:1、最底层LCDP是低代码开发框架,提供低代码的开发能力;2、CDM通用数据模型层,主要解决系统间的数据标准;3、标品-标准业务产品层, 这层是我们核心的功能层,大部分业务代码都在这里完成;为了达到能按照模块组装的功能,标品需划分好模块,各模块是相对独立的服务(类似微服务的一个服务中心);4、客户定制层,可以对标品某个模块进行扩展,也可以新建模块;对标品扩展方式, 通常有以下几种方式:1)继承标品功能进行扩展2)覆盖方式,重写某个功能3)通过扩展点的方式注入定制逻辑4)通过SPI的方式,替换掉默认逻辑 2、设计器与应用 本地开发环境和开发环境,同一个环境下,有业务应用和设计器的两个入口,需要业务应用和设计器进行实时联动的情况,则要求:1.1 所有的【业务应用】和【设计器】,共用base库和基础数据的库; 业务应用的【业务数据】使用各自的业务库(可多个);1.2 业务应用和设计器之间的互通通过配置网关(如Nginx等)的路由方式; 开发本地或者开发环境,若通过【业务的前端】入口直接访问到设计器,则需在【业务应用】的网关路由配置【设计器】的路由。 开发本地或者开发环境,若通过【设计器的前端】入口直接访问到业务系统,则需在【设计器】的网关路由配置【业务应用】的路由。 1.3 基础应用和业务应用、基础数据和设计器包含在一起,通过指定基础应用模块到对应的数据源的方式实现基础数据共享;1.4 基础应用(文件file/用户权限/资源等)单独部署;业务应用和设计器通过远程方式(RPC)进行调用; 2.1 模式一,应用和基础模块独立 总体方案:1、DB层面每个环境共用base库;主数据(用户、权限、资源等)单独建立主数据库;各自业务系统(包括设计器本身)建立自己的业务库。2、应用层面1)应用和设计器之间通过路由转发的方式相互访问;2)应用单独部署的情况,应用之间通过RPC(Dubbo)的方式进行调用;3)所有的应用AllinOne的方式部署在一起,则直接走SpringBean的方式(Injvm); 2.1.1 模式1,DB划分 2.1.2 模式1,服务调用 2.2 模式二,应用和基础模块合并 3、部署架构图 4、Oinone项目包分层示例 4.1 CDM层示例 CDM层主要定义模型,包括模型之间的关系;对于主数据类的基础服务,可以确定上层不会修改的,也可包含这部分的服务层。 4.2 标品项目示例 ├── pamirs-boot 应用启动模块,启动入口,启动过程中系统性的数据初始化│ │ └── boot 启动类的包路径│ │ └── XxxApplication 模块的应用启动类,遵循spring boot 规范│ │ └── resources/config/application-dev.yml 研发环境的yml配置文件,遵循spring boot 规范│ │ └── resources/bootstrap.yml 启动的yml配置文件,遵循spring boot 规范├── pamirs-common 通用模块 工程通用常量,传输模型,Utils等├── pamirs-major 主数据模块│ ├── pamirs-major-api 对外api包,在此包下定义 模型 服务Service,枚举常量等│ │ └── constant 常量的包路径│ │ └── enums 枚举的包路径│ │ └── model 该领域核心模型的包路径│ │ └── service 该领域对外暴露接口api的包路径│ │ └── tmodel 存放该领域的非存储模型如:用于传输的临时模型│ │ └── MajorModule 该类是Major模块的定义│ ├── pamirs-major-core api的内部逻辑实现包│ │ └── init 模块初始化工作的包路径│ │ └── manager manager是 service的一些公共逻辑,不会定义为独立的function的类│ │ └── service service是对应api工程中service接口的实现类,是模型的function├── pamirs-eip 集成模块│ ├── pamirs-eip-api 对外api包,在此包下定义 模型 服务Service,枚举常量等│ │ └── EipModule 该类是Major模块的定义│ ├── pamirs-eip-core api的内部逻辑实现包├── pamirs-item 商品模块│ ├── pamirs-item-api 对外api包,在此包下定义 模型 服务Service,枚举常量等│ │ └── ItemModule 该类是Major模块的定义│ ├── pamirs-item-core api的内部逻辑实现包│ ├── pamirs-item-view 应用PC端│ │ └── action 模型对外交互的行为的包–对前端页面开放的接口│ │ └── init 模块初始化工作的包路径│ │ └── manager manager是 service的一些公共逻辑,不会定义为独立的function的类 4.3 系统的分层 himalaya(cdm) — himalaya-major — himalaya-common — himalaya-item — himalaya-inventory — himalaya-trade — …… kailas-leo(标品项目) — kailas-leo-major — kailas-leo-item — kailas-leo-trade — kailas-leo-pay — kailas-leo-boot — …… kailas-leo-lb(客户项目)…

    2024年2月20日
    2.0K00
  • 4.1.15 框架之网关协议

    一、多端协议 协议内容格式 请求头 头信息 headerMap "sec-fetch-mode" -> "cors" "content-length" -> "482" "sec-fetch-site" -> "none" "accept-language" -> "zh-CN,zh;q=0.9" "cookie" -> "pamirs_uc_session_id=241af6a1dbba41a4b35afc96ddf15915" "origin" -> "chrome-extension://flnheeellpciglgpaodhkhmapeljopja" "accept" -> "application/json" "host" -> "127.0.0.1:8090" "connection" -> "keep-alive" "content-type" -> "application/json" "accept-encoding" -> "gzip, deflate, br" "user-agent" -> "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.192 Safari/537.36" "sec-fetch-dest" -> "empty" 图4-1-15-1 头信息 headerMap 请求地址 requestUrl 例如 http://127.0.0.1:8090/pamirs/DemoCore?scene=redirectListPage HTTP参数键值对 parameterMap url中queryString在服务端最终会转化为参数键值对。 请求体格式 请求体格式采用GraphQL协议。请求体格式分为API请求和上下文变量。以商品的test接口为例,请求格式如下。 API请求格式 query{ petShopProxyQuery { queryPage(page: {currentPage: 1, size: 1}, queryWrapper: {rsql: "(1==1)"}) { content { income id code creater { id nickname } relatedShopName shopName petTalents { id name } items { id itemName } } size totalPages totalElements } } } 图4-1-15-2 API请求格式 上下文变量 variables 请求策略requestStrategy 名称 类型 说明 checkStrategy CheckStrategyEnum 校验策略:RETURN_WHEN_COMPLETED -?全部校验完成再返回结果RETURN_WHEN_ERROR -?校验错误即返回结果 msgLevel InformationLevelEnum 消息级别:DEBUG("debug", "调试", "调试"),INFO("info", "信息", "信息"),WARN("warn", "警告", "警告"),SUCCESS("success", "成功", "成功"),ERROR("error", "错误", "错误")不设置,则只返回错误消息;上方消息级别清单,越往下级别越高。只有消息的级别高于或等于该设定级别才返回,否则会被过滤。 onlyValidate Boolean 只校验不提交数据 表4-1-15-1 请求策略requestStrategy 上下文变量式例如下。 { "requestStrategy": { "checkStrategy": "RETURN_WHEN_COMPLETED", "msgLevel":"INFO" } } 图4-1-15-3 上下文变量式例 响应体格式 协议响应内容包括data、extensions和errors三部分,extensions和errors是可缺省的。data部分为业务数据返回值。应用业务层可以在extensions中添加API返回值之外的扩展信息。extensions中包含success、messages和extra三部分,success标识请求是否成功。如果业务正确处理并返回,则errors部分为空;如果业务处理返回失败,则将错误信息添加到errors中。 正确响应格式示例如下。 { "data": { "petShopProxyQuery": { "queryPage": { "content": [ { "id": "246675081504233477", "creater": { "id": "10001" }, "relatedShopName": "oinone宠物店铺001", "shopName": "oinone宠物店铺001", "petTalents": […

    Oinone 7天入门到精通 2024年5月23日
    1.2K00
  • 如何添加数据可视化运行时依赖

    前端 package.json中新增依赖 @kunlun/data-designer-open-pc,版本跟@kunlun/dependencies的填一样 src/main.ts内导入依赖 import 'reflect-metadata'; import { VueOioProvider } from '@kunlun/dependencies'; // START 导入代码放在导入@kunlun/dependencies之后 import '@kunlun/data-designer-open-pc'; // END 导入代码放在VueOioProvider()方法执行前 VueOioProvider({ // TODO }); 后端 父pom新增依赖 <properties> <pamirs.data.visualization.version>4.7.8</pamirs.data.visualization.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>pro.shushi.pamirs.data.visualization</groupId> <artifactId>pamirs-data-visualization</artifactId> <version>${pamirs.data.visualization.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> 2.boot启动工程的pom新增依赖 <dependency> <groupId>pro.shushi.pamirs.data.visualization</groupId> <artifactId>pamirs-data-visualization-core</artifactId> </dependency> 3.application.yml配置新增依赖 pamirs: boot: modules: – datavi 注意:datavi 这个模块在业务工程和设计器指定数据源要保持一致。

    2024年5月15日
    1.5K00

Leave a Reply

Please Login to Comment