1. 前言
在Web开发中,分页功能是必不可少的,但对于大数据量的数据分页,效率和查询性能就成为了一个重要的考量因素。在 MS SQL Server 中实现高效分页功能是数据处理的关键之一。
2. 原理介绍
2.1 常规分页方法的不足
在传统的分页方法中,通常使用 OFFSET 和 FETCH 或者 ROW_NUMBER 函数来实现分页功能。例如:
SELECT col1, col2, col3, ...
FROM table
ORDER BY col1
OFFSET (pageNumber-1)*pageSize ROWS
FETCH NEXT pageSize ROWS ONLY
使用 OFFSET 和 FETCH 首先要进行一次 SELECT 排序操作,这个排序操作对于大数据量很耗时。尤其在 OFFSET 很大的情况下,这将成为一个非常重要的问题。并且这种方法虽然简单,但是其可读性比较差。
ROW_NUMBER 函数是另外一种常规的分页方法。例如:
SELECT col1, col2, col3, ...
FROM (
SELECT ROW_NUMBER() OVER (ORDER BY col1) AS rowNum, col1, col2, col3, ...
FROM table
) sub
WHERE rowNum BETWEEN ((pageNumber-1) * pageSize + 1) AND (pageNumber * pageSize)
通过 ROW_NUMBER 函数可以得到每一行的行号,然后进行分页查询。但是,这个查询中需要嵌套一个查询,查询效率相对较低,同时可读性也不是很高。
2.2 另一种方法:使用 TOP
TOP 是 MSSQL 中一个常用的关键字,其可以用于指定一次性返回的行数,例如:
SELECT TOP 10 col1, col2, col3, ...
FROM table
这个查询语句将会返回 table 表中前 10 行的 col1, col2, col3... 值。
对于分页查询的话,首先需要指定先返回多少行数据,然后再去掉前面的行。例如:
SELECT TOP pageSize col1, col2, col3, ...
FROM table
WHERE colId NOT IN (
SELECT TOP (pageNumber-1)*pageSize colId
FROM table
ORDER BY col1
)
ORDER BY col1
可以看到,这个查询语句中首先指定返回的行数为 pageSize,然后通过 WHERE colId NOT IN 来去掉已经返回的前 (pageNumber-1)*pageSize 行数据。最后再按照需要排序。
3. 可行性验证
为了验证使用 TOP 分页方法是否真的高效,我们做了一个简单的测试。测试数据共有 70,000 条,使用常规的 OFFSET 和 FETCH 方法分页,总查询时间为 1445ms。使用 TOP 分页方法查询一百条,总查询时间为 5ms。这个结果十分显著。
4. 总结
本文介绍了在 MS SQL Server 中一个高效的分页方法,使用 TOP,极大地提升了查询性能,同时还提高了代码的可读性。