SQL Server 大数据量分页

1、ROW_NUMBER() OVER()方式(SQL2012以下推荐使用)

SELECT

*

FROM

( SELECT ROW_NUMBER ( ) OVER ( ORDER BY menuId ) AS RowId,* FROM sys_menu ) AS r

WHERE

RowId BETWEEN 1 AND 10

用子查询新增一列行号(ROW_NUMBER)RowId查询,比较高效的查询方式,只有在SQL Server2005或更高版本才支持。

"BETWEEN 1 AND 10" 是指查询第1到第10条数据(闭区间),在这里面需要注意的是OVER的括号里面可以写多个排序字段。

通用用法:

--pageIndex 表示指定页

--pageSize 表示每页显示的条数

SELECT

*

FROM

( SELECT ROW_NUMBER ( ) OVER ( ORDER BY 排序字段 ) AS RowId,* FROM 表名 ) AS r

WHERE

RowId BETWEEN ( ( pageIndex - 1 ) * pageSize + 1 )

AND ( pageIndex * PageSize )

2、offset fetch next方式(SQL2012及以上的版本才支持:推荐使用 )

--offset fetch next方式查询,最高效的查询方式,只有在SQL Server2012或更高版本才支持

SELECT

*

FROM

sys_menu

ORDER BY

menuId offset 0 ROWS FETCH NEXT 10 ROWS ONLY

offset 是跳过多少行, next是取接下来的多少行, 句式 offset...rows fetch next ..rows only ,注意rows和末尾的only 不要写漏掉了,并且这种方式必须要接着Order by XX 使用,不然会报错。

举例:

SELECT

*

FROM

table1 a

WHERE

1=1 and a.id = '1'

ORDER BY

a.create_time DESC offset 102080 ROWS FETCH NEXT 30 ROWS ONLY

通用用法:

--pageIndex 表示指定页

--pageSize 表示每页显示的条数

SELECT

*

FROM

表名

ORDER BY

排序字段 offset ( ( pageIndex - 1 ) * pageSize ) ROWS FETCH NEXT pageSize ROWS ONLY

3、top not in方式 (不推荐)

--查询第11-20条记录

SELECT TOP

10 menuId, *

FROM

sys_menu

WHERE

menuId NOT IN ( SELECT TOP 10 menuId FROM sys_menu )

这条语句的原理是先查询1-10条记录的ID,然后再查询ID不属于这1-10条记录的ID,并且只需要10条记录,因为每页大小就是10,这就是获取到的第11-20条记录,这是非常简单的一种写法。

另外IN语句与NOT IN语句类似,这是NOT IN的写法,但是这种写法数据量大的话效率太低。

通用用法:

--pageIndex 表示指定页

--pageSize 表示每页显示的条数

SELECT TOP

pageSize menuId, *

FROM

sys_menu

WHERE

menuId NOT IN ( SELECT TOP ( ( pageSize - 1 ) * pageIndex ) menuId FROM sys_menu )

4、通过升序与降序方式进行查询分页(不推荐)

--查询第11-20条记录

SELECT * FROM(

SELECT TOP 10 * FROM(

SELECT TOP 20 * FROM sys_menu ORDER BY menuId ASC)

AS TEMP1 ORDER BY menuId DESC)

AS TEMP2 ORDER BY menuId ASC

这条语句首先查询前20条记录,然后在倒序查询前10条记录(即倒数10条记录),这个时候就已经获取到了11-20条记录,但是他们的顺序是倒序,所以最后又进行升序排序。

通用用法:

--pageIndex 表示指定页

--pageSize 表示每页显示的条数

SELECT * FROM(

SELECT TOP pageSize * FROM(

SELECT TOP ((pageIndex - 1) * pageSize +(pageSize*2)) * FROM sys_menu ORDER BY menuId ASC)

AS TEMP1 ORDER BY menuId DESC)

AS TEMP2 ORDER BY menuId ASC

5、采用MAX(ID)或者MIN(ID)函数(不推荐)

--查询第11-20条记录

SELECT TOP 10 * FROM sys_menu WHERE menuId>

(SELECT MAX(menuId) FROM(SELECT TOP 10 menuId FROM sys_menu ORDER BY menuId) AS TEMP1) --(第10条的id)

先把第10条记录的id找出来(当然这里面是直接使用MAX()进行查找,MIN()函数的用法也是类似的),然后再对比取比第10条记录的id大的前10条记录即为我们需要的结果。这里要注意开始时的边界值调整。

通用用法:

--pageIndex 表示指定页

--pageSize 表示每页显示的条数

SELECT TOP pageSize * FROM sys_menu WHERE menuId>

(SELECT MAX(menuId) FROM(SELECT TOP ((PageIndex-1)*PageSize) menuId FROM sys_menu ORDER BY menuId) AS TEMP1) --(第10条的id)

方案1、2、5都需要依赖一个排序Id(这个Id要么是个排序列,要么是个主键)。方案3、4则效率太低,完全不推荐。

相关推荐
SelectDB12 小时前
SelectDB 是哪个公司的?是国产数据库吗?一篇讲清飞轮科技与 Apache Doris 的关系
数据库
这个DBA有点耶12 小时前
库内计算推理:一条SQL背后的算子融合,和外挂方案差了几次网络往返
数据库·人工智能·sql
这个DBA有点耶14 小时前
函数索引的“完全一致”有多苛刻:写法、字符集、类型,差一处就失效
数据库·mysql·代码规范
星恒随风14 小时前
MySQL 从零入门(三):表的约束详解
linux·服务器·数据库·笔记·mysql
Alluxio15 小时前
Alluxio + OCI:为 AI 工作负载实现亚毫秒访问延迟与可扩展吞吐
运维·数据库·人工智能·分布式·缓存·ai·语言模型
数据库急诊室_阿哲18 小时前
一次加索引建议的复核记录:从报告到签字
数据库·ai数据库
青瓦梦滋19 小时前
Redis主从复制
服务器·数据库·redis·缓存·bootstrap
慧都小妮子20 小时前
Wyn商业智能国产数据库适配:数据接入、分析缓存与审计日志验证清单
数据库·数据分析·数据可视化·审计日志·商业智能
Joy T21 小时前
Redis Lua 原子限流:Lua 脚本、竞态条件与并发控制
数据库·redis·lua·限流·竞态条件·redis scripting
杨凯凡21 小时前
MySQL 死锁怎么排查?InnoDB 锁等待与 Spring Boot 整事务重试实战
数据库·spring boot·mysql