解决几百万条以上数据分页让人蛋疼的 SQL2005, SQL2008最后一页卡死,最后一页查询超时的源码
来源:互联网 发布:一体智能马桶 知乎 编辑:程序博客网 时间:2024/04/29 17:17
转载:http://www.cnblogs.com/jirigala/archive/2012/03/08/2385895.html
应该很多人也遇到过这个问题,大概在2年前我也遇到过标题中的问题,当时研究了几天很是纠结没能彻底解决问题,后来也找了很多方法没能解决问题。最近又遇到这个问题,实在是不解决也不行了,冷静的想了想,完善了一下分页查询的方法,现在把代码贴上,给大家参考,若有什么漏洞,请及时联系吉日嘎拉,有错我会积极修正。希望不要重复浪费生命,直接拿过去用就可以了,在通用权限管理系统组件里也用了这个方法在进行分页。
最近维护一个每天有10万多IP访问的网站,也是用了这个分页存储过程,分页效率还可以,最后一页没在出现卡死状态,若有问题及时联系作者QQ:252056973,欢迎大家交流分享。当系统有少数几个用户实用时问题也不严重,但是系统每时每刻都有很多人访问时那就闹心了,很容易产生网站效率极低的,访问量严重下降的趋势。
最后一页分页一卡死,整个网站的性能都会非常明显的下降,不知道为啥,微软有这个BUG一直没处理好。希望SQL2012里不要有这个问题就好了
-- =============================================-- Author: 吉日嘎拉-- Create date: 2012年02月23日-- Description: 2012年02月23日编码规范化-- =============================================ALTER PROCEDURE [dbo].[GetRecordByPage] @TableName VARCHAR(4000), -- 表名 @SelectField VARCHAR(4000), -- 要显示的字段名(不要加select) @WhereConditional VARCHAR(4000), -- 查询条件(注意: 不要加 where) @SortExpression VARCHAR(255), -- 排序索引字段名 @PageSize INT = 20, -- 页大小 @PageIndex INT = 1, -- 页码 @RecordCount INT OUTPUT, -- 返回记录总数 @SortDire VARCHAR(5) = 'DESC' -- 设置排序类型, 非 0 值则降序ASBEGIN DECLARE @commandText VARCHAR(8000) -- 主语句 DECLARE @TopN INT -- 获取前几条记录 DECLARE @PageCount INT -- 总共会是几页 DECLARE @TopLimit INT -- 获取多少条记录 DECLARE @SQLRowCount NVARCHAR(4000) -- 用于查询记录总数的语句 DECLARE @SQLOrder VARCHAR(400) -- 排序类型 DECLARE @SQLTemp VARCHAR(4000) -- 临时变量 SET @SortExpression = LTRIM(RTRIM(@SortExpression)) SET @SortDire = UPPER(LTRIM(RTRIM(@SortDire))) -- 这里是计算整体记录行数 IF @RecordCount IS NULL BEGIN IF @WhereConditional != '' BEGIN SET @SQLRowCount = 'SELECT @RecordCount=COUNT(1) FROM ' + @TableName + ' WHERE ' + @WhereConditional END ELSE BEGIN SET @SQLRowCount = 'SELECT @RecordCount=COUNT(1) FROM ' + @TableName END END -- SELECT @RecordCount=@@ROWCOUNT EXEC sp_executesql @SQLRowCount, N'@RecordCount INT OUT', @RecordCount out IF @RecordCount IS NULL BEGIN SET @RecordCount = 0 END -- 这里是控制页数最多少 SET @PageCount = @RecordCount / @PageSize + 1 -- 这里检查当前页的有效性 IF (@PageIndex < 1) BEGIN SET @PageIndex = 1 END -- 这里限制最后一页的有效性 IF (@PageIndex > @PageCount) BEGIN SET @PageIndex = @PageCount END IF @SortDire != 'ASC' BEGIN SET @SQLTemp = '<(SELECT MIN' SET @SQLOrder = ' ORDER BY ' + @SortExpression + ' DESC' END ELSE BEGIN set @SQLTemp = '>(SELECT MAX' set @SQLOrder = ' ORDER BY ' + @SortExpression + ' ASC' END -- 这里是调试信息 -- SELECT @SQLOrder -- 获取几条数据? 吉日嘎拉 2010-11-02 更新 SET @TopN = @RecordCount - @PageSize * (@PageIndex - 1) IF @TopN > @PageSize BEGIN SET @TopN = @PageSize END SET @TopLimit = @PageSize * (@PageIndex - 1) IF @TopLimit > @RecordCount BEGIN SET @TopLimit = @RecordCount END SET @commandText = 'SELECT TOP ' + STR(@TopN) + ' ' + @SelectField + ' FROM ' + @TableName + ' WHERE ' + @SortExpression + @SQLTemp + '(' + RIGHT(@SortExpression, LEN(@SortExpression) - CHARINDEX('.', @SortExpression)) + ') FROM (SELECT TOP ' + STR(@TopLimit) + ' ' + @SortExpression + ' FROM ' + @TableName + @SQLOrder + ') AS TableTemp)' + @SQLOrder IF @WhereConditional != '' SET @commandText = 'SELECT TOP ' + STR(@TopN) + ' ' + @SelectField + ' FROM ' + @TableName + ' WHERE ' + @SortExpression + @SQLTemp + '(' + RIGHT(@SortExpression, LEN(@SortExpression) - CHARINDEX('.',@SortExpression)) + ') FROM (SELECT TOP ' + STR(@TopLimit) + ' ' + @SortExpression + ' FROM ' + @TableName + ' WHERE ' + @WhereConditional + ' ' + @SQLOrder + ') AS TableTemp) AND ' + @WhereConditional + ' ' + @SQLOrder IF @PageIndex = 1 BEGIN -- 第一页的显示效率提高 SET @SQLTemp = '' IF @WhereConditional != '' SET @SQLTemp = ' WHERE ' + @WhereConditional SET @commandText = 'SELECT TOP ' + STR(@TopN) + ' ' + @SelectField + ' FROM ' + @TableName + @SQLTemp + ' ' + @SQLOrder END ELSE BEGIN -- 解决大数据最有一页卡死的问题 IF @PageIndex = @PageCount BEGIN IF @SortDire = 'ASC' BEGIN SET @SQLOrder = ' ORDER BY ' + @SortExpression + ' DESC' END ELSE BEGIN SET @SQLOrder = ' ORDER BY ' + @SortExpression + ' ASC' END SET @SQLTemp = '' IF @WhereConditional != '' SET @SQLTemp = ' WHERE ' + @WhereConditional SET @commandText = 'SELECT TOP ' + STR(@TopN) + ' ' + @SelectField + ' FROM ' + @TableName + @SQLTemp + ' ' + @SQLOrder SET @commandText = 'SELECT ' + @SelectField + ' FROM (' + @commandText + ') AS TableTemp ORDER BY ' + @SortExpression + ' ' + @SortDire END END EXEC (@commandText) -- 这个是调试程序用的 -- SELECT @commandText END
- 解决几百万条以上数据分页让人蛋疼的 SQL2005, SQL2008最后一页卡死,最后一页查询超时的源码
- asp.net显示第一页、上一页、下一页和最后一页的分页显示数据表的数据
- eXtremeComponents 的最后一页
- hibernate分页,点击最后一页时查询速度很慢的解决方法
- 分享:用PreRender解决DataGrid分页最后一页行数不满的排版问题
- 也谈解决DataGrid分页最后一页行数不满的排版问题
- 关于删除Ext分页表格最后一页全部数据后页面无效的问题
- DataGrid 分页—最后一页
- 分页实现-----首页、上一页、下一页、最后一页
- DATAGRID分页,增加首页、最后一页(源码)
- Qreport 填满最后一页的空白
- ireport根据分组分页时,最后一页没有数据
- 分页栏的web标准实现(始终显示第一页的页码和最后一页的页码)
- 关于MVC中使用JqGrid插件分页时无法显示分页按钮(首页、上一页、下一页、最后一页)的原因
- 为什么每次上滑分页后只显示最后一页呢?上一页就不显示了,应该是追加的
- 集合分页展示,补全最后一页
- 在分页后web报表的最后一页补足空行的方法
- 2011 最后一页
- aspnet_Roles,aspnet_Users,aspnet_UsersInRoles。。。。
- java时间大小比较
- 动态调用webservice的三种方式
- android横向滚动屏幕特效分析
- 《第十三周任务二----1》动物叫,根据main函数完成相关类。
- 解决几百万条以上数据分页让人蛋疼的 SQL2005, SQL2008最后一页卡死,最后一页查询超时的源码
- Android应用不完全退出问题
- 在多层架构中datareader传递的问题
- Linux内存管理图解
- 读取APK中versionCode信息
- poj 2464 Brownie Points II(两棵线段树——线段树区间和)
- 装饰设计模式
- Log4j输出日志教程
- SQL Server 中 RAISERROR 的用法