sqlserver 通用存储过程分页代码(附使用ROW_NUMBER()和不使用ROW_NUMBER()两种情况性能分析)
在SQL Server中,分页查询是数据库操作中的常见需求,特别是在大数据量的场景下,用于显示数据列表的分页能够显著提升用户体验。本篇将详细探讨两种不同的分页实现方式,一种是使用ROW_NUMBER()函数,另一种是不使用ROW_NUMBER()函数,并分析它们的性能差异。 ROW_NUMBER()函数在SQL Server中被广泛用于生成行号,常用于分页查询。它为每一行提供一个唯一的整数值,可以根据这个值进行排序和分页。以下是一个使用ROW_NUMBER()的分页存储过程示例: ```sql ALTER PROCEDURE [dbo].[sp_PagerWithROW_NUMBER] @tblName varchar(255), @strGetFields varchar(1000) = '*', @pkName nvarchar(50)='ID', @strOrder varchar(255)='', @strWhere varchar(1500) = '', @pageIndex int = 1, @pageSize int = 20, @recordCount int=0 out, @doCount bit=0 AS BEGIN DECLARE @sql nvarchar(4000), @sqltemp nvarchar(1000), @strCount nvarchar(1000) SET @sql = 'SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY ' + @strOrder + ') AS RowNum FROM ' + @tblName IF (@strWhere != '') SET @sql = @sql + ' WHERE ' + @strWhere SET @sql = @sql + ') AS TempTable WHERE RowNum BETWEEN ' + CAST((@pageIndex - 1) * @pageSize + 1 AS nvarchar) + ' AND ' + CAST(@pageIndex * @pageSize AS nvarchar) IF (@doCount != 0) BEGIN IF (@strWhere != '') SET @strCount = 'SET @num=(SELECT COUNT(1) FROM ' + @tblName + ' WHERE ' + @strWhere + ')' ELSE SET @strCount = 'SET @num=(SELECT COUNT(1) FROM ' + @tblName + ')' EXECUTE sp_executesql @strCount, N'@num INT output', @RecordCount output END EXECUTE sp_executesql @sql, N'@RecordCount INT', @RecordCount END ``` 这个存储过程通过ROW_NUMBER()生成行号,然后根据页码和每页大小选择对应的数据行。如果需要统计记录总数,会额外执行一次COUNT(1)操作。 另一方面,不使用ROW_NUMBER()的分页方式通常依赖于主键或唯一标识符进行分页,例如通过计算范围来获取指定页的数据。以下是一个示例: ```sql ALTER PROCEDURE [dbo].[sp_PagerWithoutROW_NUMBER] @tblName varchar(255), @strGetFields varchar(1000) = '*', @pkName nvarchar(50)='ID', @strOrder varchar(255)='', @strWhere varchar(1500) = '', @pageIndex int = 1, @pageSize int = 20, @recordCount int=0 out, @doCount bit=0 AS BEGIN DECLARE @sql nvarchar(4000), @sqltemp nvarchar(1000), @strCount nvarchar(1000) SET @sql = 'SELECT ' + @strGetFields + ' FROM ' + @tblName IF (@strWhere != '') SET @sql = @sql + ' WHERE ' + @strWhere IF (@strOrder != '') SET @sql = @sql + ' ORDER BY ' + @strOrder IF (@doCount != 0) BEGIN IF (@strWhere != '') SET @strCount = 'SET @num=(SELECT COUNT(1) FROM ' + @tblName + ' WHERE ' + @strWhere + ')' ELSE SET @strCount = 'SET @num=(SELECT COUNT(1) FROM ' + @tblName + ')' EXECUTE sp_executesql @strCount, N'@num INT output', @RecordCount output END IF (@PageIndex > 1) BEGIN SET @sqltemp = 'SELECT * FROM (SELECT TOP ' + CAST(@pageSize AS nvarchar) + ' * FROM (SELECT TOP ' + CAST((@pageIndex - 1) * @pageSize AS nvarchar) + ' * FROM ' + @tblName + ' WHERE ' + @strWhere + ' ORDER BY ' + @strOrder + ') t ORDER BY ' + @strOrder + ' DESC) t2 ORDER BY ' + @strOrder SET @sql = @sqltemp END EXECUTE sp_executesql @sql, N'@RecordCount INT', @RecordCount END ``` 这种方法需要两次查询:第一次获取前一页的最后一个主键值,第二次根据该值选择下一页的数据。这种方式的优点是在某些情况下可能避免了全表扫描,但缺点是逻辑复杂且可能无法精确处理并发更新导致的主键跳跃问题。 性能分析方面,通常使用ROW_NUMBER()的分页方式在大数据量时更为高效,因为它只需要一次查询就可以完成分页和排序,而无需额外的子查询。不过,如果表上有合适的索引,不使用ROW_NUMBER()的方式也可能有较好的性能。此外,统计记录总数的开销在两种方法中都是存在的,但在实际应用中,如果不需要实时的总记录数,可以考虑通过缓存或其他手段减少这部分计算。 选择哪种分页方式取决于具体的应用场景,包括数据量、表结构、索引策略以及对性能和复杂性的权衡。在SQL Server中,通常推荐使用ROW_NUMBER()函数进行分页,以获得更好的可读性和性能。然而,实际情况应根据数据库的特性和业务需求来决定。

























- 粉丝: 4
我的内容管理 展开
我的资源 快来上传第一个资源
我的收益
登录查看自己的收益我的积分 登录查看自己的积分
我的C币 登录后查看C币余额
我的收藏
我的下载
下载帮助


最新资源
- CoinExchange-云原生微服务架构搭建与部署资源
- 农产品电子商务中生鲜农产品固定自提点布局评价标准探讨(1).docx
- 5篇实用软件技术合同范本(1).docx
- 人工智能对中学教学的影响与应对策略(1).docx
- 电气自动化技术在电气工程中的应用研究梁栋(1).docx
- 具身认知视角下高职信息化实践教学体系研究(1).docx
- 计算机网络安全模拟题3(1).doc
- leetcode-vmware虚拟机安装资源
- Web安全防护系统的实现与分析(1).doc
- 计算机网络入侵检测技术探讨(1).docx
- 试论混合学习模式在中职计算机教学中的应用(1)(1).docx
- 网上蛋糕商铺网站的分析与设计毕业论文设计(1).pdf
- 软件工程-学生宿舍管理系统(1).docx
- 计算机组成原理 第18讲虚拟存储器.ppt
- 【推荐下载】紧盯当今制造业三大风口:3D打印大数据智能机器人(1).doc
- 互联网商业模式创新研究(1).docx


