SqlServer 分页查询,很多人习惯用 row_number 进行排序,在此排序的基础上利用 row_number 来处理分页。 但 row_number 这个函数有个缺点,表的行数越多时,大到十几吨行或几十万行时,row_number 实现的翻页,页码越大查询效果越慢,甚至直接查询超时。
下面给出几种翻页的实现方法 ,供大家测试和参考,废话不多说,直接上语句。
sql
SELECT COUNT(*) As Total FROM V_ME_mom_order_List
WHERE cOrgCode LIKE '01%' AND ( 1=1 OR ISNULL(cInvCode,'')='') AND ( 1=1 OR ISNULL(cInvCCode,'')='') AND ( 1=1 OR ISNULL(cDepCode,'')='')
--1. ROW_NUMBER 正向======== > 起始行 + TOP 页大小
SELECT Top 500 1 FROM
(
SELECT row_number()over(order by MOMID) as rowNum,
1 as c
FROM V_ME_mom_order_List WITH(NOLOCK)
WHERE cOrgCode LIKE '01%'
AND ( 1=1 OR ISNULL(cInvCode,'')='')
AND ( 1=1 OR ISNULL(cInvCCode,'')='')
AND ( 1=1 OR ISNULL(cDepCode,'')='')
) t
WHERE t.rowNum > 136500 order by t.rowNum asc
--2. ROW_NUMBER 正向======== > 起始行 + <= 结束行
SELECT 1 FROM (
SELECT row_number()over(order by MOMID) as rowNum,
1 as c
FROM V_ME_mom_order_List WITH(NOLOCK)
WHERE cOrgCode LIKE '01%'
AND ( 1=1 OR ISNULL(cInvCode,'')='')
AND ( 1=1 OR ISNULL(cInvCCode,'')='')
AND ( 1=1 OR ISNULL(cDepCode,'')='')
) t
WHERE t.rowNum > 136500 AND t.rowNum <= 13700 order by t.rowNum asc
--3. ROW_NUMBER 反向查询
SELECT * FROM (
SELECT row_number()over(order by MOMID desc) as rowNum,
*
FROM V_ME_mom_order_List WITH(NOLOCK)
WHERE cOrgCode LIKE '01%'
AND ( 1=1 OR ISNULL(cInvCode,'')='')
AND ( 1=1 OR ISNULL(cInvCCode,'')='')
AND ( 1=1 OR ISNULL(cDepCode,'')='')
) t
WHERE t.rowNum > 0 AND t.rowNum <= 52
order by t.rowNum asc
--4. OFFSET 正向
SELECT 1
FROM V_ME_mom_order_List
WHERE cOrgCode LIKE '01%'
AND ( 1=1 OR ISNULL(cInvCode,'')='')
AND ( 1=1 OR ISNULL(cInvCCode,'')='')
AND ( 1=1 OR ISNULL(cDepCode,'')='') -- 如果有的话
ORDER BY MOMID ASC -- 分页必须指定排序,否则结果不可靠
OFFSET (274 - 1) * 500 ROWS -- 计算需要跳过的行数
FETCH NEXT 500 ROWS ONLY; -- 获取当前页的100条数据
--5. OFFSET 反向
SELECT *
FROM V_ME_mom_order_List
WHERE cOrgCode LIKE '01%'
AND ( 1=1 OR ISNULL(cInvCode,'')='')
AND ( 1=1 OR ISNULL(cInvCCode,'')='')
AND ( 1=1 OR ISNULL(cDepCode,'')='') -- 如果有的话
ORDER BY MOMID DESC -- 分页必须指定排序,否则结果不可靠
OFFSET 0 ROWS -- 计算需要跳过的行数
FETCH NEXT 52 ROWS ONLY; -- 获取当前页的100条数据
上面几种方式 测试下来感觉 正向、offset 的效果最好。如果有 嵌套查询、子查询这些情况,子查询用 with 语句效果更好。