Sqltoy ORM框架之:分页查询(没错包含你所有所有能用到的关系型数据库分页)...

本文探讨了数据库分页的优化方法与实现策略,包括性能考量、SQL性能优化及各类数据库分页机制,旨在帮助开发者高效地进行分页查询。

      本来打算再过一阵子整体介绍一下个人的Sqltoy ORM框架,但经历几家公司,发觉在数据库操作层面,就算是很大的公司仍然在使用非常古老的做法,为了给大家一点建议,分享一下有关数据库分页的做法。

     1、数据库分页一般分两步,第一:取总记录数,第二:根据页号和总记录数以及每页条数封装特定数据库分页查询语句。

     2、针对普通开发者,应该提供一个统一的分页封装,将取记录数和取分页记录进行有效封装,让开发者只需要一步操作即可完成分页查询,这里一般需要封装一个paginationModel,里面有pageNo,pageSize,rows<List>,totalRecord等属性。

     分页应该充分考虑性能问题,其关键点:

1、提取查询记录数的sql,一般要截取 from 前部分,组成 select count(1) from xxxxx,同时需要剔除掉 整个sql中的 group by 以及order by ,这样有助于提升sql执行性能

2、需要考虑sql语句中存在 with xxx as () 模式的语句,大多数公司的框架根本就没有考虑这种问题,导致sql一旦比较特殊查询就报错。 

      这里个人提供一下各类数据库的分页机制:

1、mysql:select * from xx   limit :start,:pageSize

2、oracle12c和sqlserver2012:select * from xxx  offset ? rows fetch next ? rows only 

3、oracle11g以及之前,分两种情况

    A:排序:SELECT * FROM (SELECT ROWNUM page_row_id,SAG_Paginationtable.* FROM (rejectWithAsSql这括号里就是你写的sql ) SAG_Paginationtable  ) WHERE  page_row_id<=? and page_row_id >?

    B:不排序:SELECT * FROM (SELECT ROWNUM page_row_id,SAG_Paginationtable.* FROM   (rejectWithAsSql这括号里就是你写的sql ) SAG_Paginationtable where ROWNUM <=?  ) WHERE  page_row_id >?

4、sqlserver2012之前的版本

    SELECT sag_sqlserver_tmp.*
   FROM (SELECT ROW_NUMBER() OVER(order by tempColumn) as page_row_id,SAG_Paginationtable.*
   FROM ( select top 40 tempColumn=0,* from rejectWithAsSql ) SAG_Paginationtable ) sag_sqlserver_tmp
where sag_sqlserver_tmp.page_row_id >?

   sqlserver第一个top 地方不可以用?形式,必须用数字替代进去。

   (当然sqlserver的处理还需要考虑是否union查询,如果是union则必须将整个查询语句包裹起来增加select  * from(你的unionsql) as xxx)

5、db2:

   SELECT t_sag_pageTable.* FROM
        (SELECT rownumber() over() as page_row_id,SAG_Paginationtable.*
         FROM (rejectWithAsSql:你的sql语句被裹在这里 ) SAG_Paginationtable ) t_sag_pageTable where t_sag_pageTable.page_row_id <=? and t_sag_pageTable.page_row_id >?

6、informix:

   SELECT SKIP ? FIRST ?  SAG_Paginationtable.* FROM (rejectWithSql) SAG_Paginationtable

7、POSTGRESQL和sqlite

    select * from xxxtable limit ? offset ?

8、sybase ASE

   sybase得通过临时表,比较变态一点,但一定要注意方式(临时表的名字建议用"#SAG_TMP_" + System.nanoTime()来组成),一定先用top提取部分数据插入临时表,避免全量查询插入临时表

   select top ? page_row_id=identity(12),sag_tmp_table.* into #tmptable from (你的sql) sag_tmp_table

9、sybase iq:

    类似于ASE,但注sql中的 order by,IQ子查询中不支持order by,需要将order by 提取到外边

 

   当然分页过程中有些数据库需要注意一些细节,以sybase 为例首先分简单sql和复杂sql,简单sql其实就不需要变成select * from (你的sql) into #table 这种模式,可以直接select top ?,* from xxx into #tmp,即在你得sql查询部分剔除select 换成select top ? ,

    短短这些应该无法全部表达需要注意的点和优化的地方,主要是给大家点建议。要完整的实现各类数据库的有效分页机制,确实需要大量的项目实践,sqltoy经历了无数项目,也经历了几乎所有能用到的关系型数据库,有意的去发展才收集了这些问题的解决机制。

     当然sqltoy的特性并不是简单的强调分页,它已经成为一个完整的O/R Mapping解决机制,集mybatis和hibernate的优点,同时有自己的特色,下次会完整介绍并进行开源。

 

    

    

sqltoy-orm是比hibernate+myBatis更加贴合项目的orm框架,具有hibernate增删改的便捷性同时也具有比myBatis更加灵活优雅的自定义sql查询功能。 sqltoy-orm支持以下数据库: oracle 从oracle11g到19c db2 9.5+,建议从10.5 开始 mysql 支持5.6、5.7、8.0 版本 postgresql 支持9.5 以及以上版本 sqlserver 支持2008到2019版本,建议使用2012或以上版本 sqlite sybase_iq 支持15.4以上版本,建议使用16版本 elasticsearch 只支持查询,版本支持5.7+版本,建议使用7.3以上版本 clickhouse mongodb (只支持查询) sqltoy-orm特性: 1、根本上杜绝了sql注入问题,sql支持写注释、sql文件动态更新检测,开发时sql变更会自动重载。 2、最直观的sql编写模式,当查询条件稍微复杂一点的时候就会体现价值,后期变更维护的时候尤为凸显。 3、极为强大的缓存翻译查询:巧妙的结合缓存减少查询语句表关联,极大简化sql和提升性能。 4、最强大的分页查询:很多人第一次了解到何为快速分页分页优化这种极为巧妙的处理,还有在count语句上的极度优化。 5、跨数据库函数方言替换,如:isnull/ifnull/nvl、substr/substring 等不同数据库sqltoy-orm特点: 1、最优雅直观的sql编写模式 2、天然防止sql注入,执行过程 3、最强大的分页查询 4、最巧妙的缓存应用,将多表关联查询尽量变成单表 5、跨数据库 6、提供行列转换(数据旋转),避免写复杂的sql或存储过程,用算法来化解对sql的高要求,同时实现数据库无关(不管是mysql还是sqlserver) 7、提供分组汇总求平均算法(用算法代替sql避免跨数据库语法不一致) 8、分库分表 9、五种非数据库相关主键生成策略 10、elastic原生查询支持 11、elasticsearch-sql 插件模式sql模式支持     sqltoy-orm框架系统 更新日志: v4.18.22 1、在findEntity中EntityQuery可以设置fetchSize 2、在sqltoyContext中可以全局设置fetchSize,例如 spring.sqltoy.fetchSize=200 3、convertType 支持空集合返回空集合 4、针对一些特殊原因导致表名是数据库关键词的处理支持
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值