对于逻辑分页与物理分页的分析与选择(MyBatis-Plus的分页实现),理解两种分页的异同点

背景:

写分页查询时,对于手续费账单分页查询需求的实现分析。

分页查询

因为项目中大多都是用了ORM框架(多为Mybatis/MyBatis-Plus),所以分页查询可以使用框架自带的分页插件,当然也可以手写SQL来实现分页查询,这属于两种分页方式。前者为逻辑分页(Mybatis为逻辑分页,MyBatis-Plus为物理分页),后者为物理分页。

逻辑分页:逻辑分页依赖于查询结果集(Java代码侧)。其是先查询出所有的数据,再根据分页要求筛选出合适的数据进行分页。它是半自动化的一个分页(因为需要传递相关分页参数,所以是半自动化的);
物理分页:物理分页依赖于SQL语句(数据库侧)。其是使用数据库自带的limit关键字进行数据分页,只查询出分页的数据,数据库返回的数据就是分页结果。物理分页就是手写SQL语句实现的分页。

在开发中,这两种分页方式需要根据实际需求进行选择。这里只针对目前我涉及到的手续费账单分页查询分析:

  1. 数据量: 手续费账单出账周期为月,所以数据量却不会特别大,因此哪怕查询全部手续费账单数据SQL执行速度也很快。所以从数据量维度看分页可以使用逻辑分页,且因为逻辑分页只会查询一次数据库,之后就会把手续费账单数据存在内存中,不会像物理查询一样每次查询请求过来都会去访问数据库,减轻了对数据库的负担。
  2. 服务器: 虽然逻辑分页一次性将所有的数据读取至内存中,占用了较大的内存空间;物理分页每次只读取所需的数据占用内存比较小,但手续费账单查询对于商户侧应该更注重商户体验,存在内存中之后会显著减少对数据库的访问,基于内存的数据操作加快了请求响应速度,对于服务器的内存压力则可以通过硬件升级去弥补(内部管理侧则可以考虑使用物理分页,但一样需要综合数据量及其他性能影响)。
  3. 实时性: 逻辑分页一次性将数据全部查询出来然后存储在内存中,如果数据库中的数据在第一次查询之后发生了改变,逻辑分页就不能够获取最新数据(因为内存的数据不能自动更新数据),可能导致脏数据的出现,实时性较低;而物理分页每一次分页都需要从数据库中进行查询,这样能够获取数据库中数据的最新状态,实时性较高。但对于手续费账单查询这个需求来说,因为手续费账单出账周期为月,所以对数据实时性要求是很低的,因此可以直接忽略掉逻辑分页的数据一致性问题选择逻辑分页。

综上,选择使用逻辑分页实现分页查询手续费账单需求。但对于手续费账单明细等数据量比较大的需求还是考虑选择使用MyBatis-Plus自带的分页插件(PaginationInterceptor:配置简单)进行物理分页实现分页查询需求。但使用MyBatis-Plus的物理分页也会有一定问题,如虽然通过调用其API实现分页查询非常方便,但是这并不能保证生成的SQL语句就是最优的。特别是在一些复杂的查询场景下,很可能需要手动编写SQL语句,进行优化处理,才能提高查询效率。

总之,MyBatis-Plus虽然是一个很好的增强工具包可以加速我们开发速度并减少开发代码量,但是在使用它的同时需要注意性能问题,尽可能做到合理使用API和高效优化SQL查询,以免出现效率和内存问题。

个人思考:

需求在实现之前应该详细分析,找到最优解,如手续费账单分页查询需求如不考虑分页方式时可能会在后续应用时造成效率和内存问题。即便选择了使用逻辑查询,也可以再分析下不同分页插件的使用方案,或者采用分片分页等更合适的策略来调整查询效率。

你可能感兴趣的:(mybatis,数据库,java)