在處理千萬級數據量的分頁查詢時,傳統的 TOP N 或 NOT IN 方式性能極差。本文介紹一個經過優化的通用分頁存儲過程 CN5135_SP_Pagination,支持動態表名、多字段排序、複雜篩選與分組,適合企業級應用。
NewsID Desc, OrderRows Asc)存儲過程通過動態構建排序條件,自動識別排序方向(ASC/DESC)並提取排序列的數據類型,針對字符類型進行特殊處理。核心思想是利用「游標式」分頁:記住上一頁最後一條記錄的排序值,下一頁直接從該值之後開始查找,避免了大偏移量掃描。
CREATE PROCEDURE CN5135_SP_Pagination
(
@Tables varchar(1000),
@PrimaryKey varchar(100),
@Sort varchar(200) = NULL,
@CurrentPage int = 1,
@PageSize int = 10,
@Fields varchar(1000) = '*',
@Filter varchar(1000) = NULL,
@Group varchar(1000) = NULL
)
AS
BEGIN
/* 默認排序處理 */
IF @Sort IS NULL OR @Sort = ''
SET @Sort = @PrimaryKey;
/* 解析排序方向與列 */
DECLARE @strSortColumn varchar(200), @Operator char(2);
IF CHARINDEX('DESC', @Sort) > 0
BEGIN
SET @strSortColumn = REPLACE(@Sort, 'DESC', '');
SET @Operator = '<=';
END
ELSE
BEGIN
IF CHARINDEX('ASC', @Sort) = 0
SET @strSortColumn = REPLACE(@Sort, 'ASC', '');
SET @Operator = '>=';
END
/* 獲取排序列數據類型 */
DECLARE @type varchar(100), @prec int;
SELECT @type = t.name, @prec = c.prec
FROM sysobjects o
JOIN syscolumns c ON o.id = c.id
JOIN systypes t ON c.xusertype = t.xusertype
WHERE o.name = @SortTable AND c.name = @SortName;
/* 字符類型補全長度 */
IF CHARINDEX('char', @type) > 0
SET @type = @type + '(' + CAST(@prec AS varchar) + ')';
/* 動態構建分頁查詢SQL... */
/* 此處省略具體動態SQL構建邏輯 */
END
線上演示地址:https://www.cn5135.com/_App/Enterprise/QueryResult.ASPx