解决几百万条以上数据分页让人蛋疼的 SQL2005, SQL2008最后一页卡死,最后一页查询超时的源码

首先,非常感谢 吉日嘎啦 的无私贡献,为我们解决这个问题~

解决几百万条以上数据分页让人蛋疼的 SQL2005, SQL2008最后一页卡死,最后一页查询超时的源码 

View Code
  1 -- =============================================
2 -- Author: 吉日嘎拉
3 -- Create date: 2012年02月23日
4 -- Description: 2012年02月23日编码规范化
5 -- =============================================
6 ALTER PROCEDURE [dbo].[GetRecordByPage]
7 @TableName VARCHAR(4000), -- 表名
8 @SelectField VARCHAR(4000), -- 要显示的字段名(不要加select)
9 @WhereConditional VARCHAR(4000), -- 查询条件(注意: 不要加 where)
10 @SortExpression VARCHAR(255), -- 排序索引字段名
11 @PageSize INT = 20, -- 页大小
12 @PageIndex INT = 1, -- 页码
13 @RecordCount INT OUTPUT, -- 返回记录总数
14 @SortDire VARCHAR(5) = 'DESC' -- 设置排序类型, 非 0 值则降序
15 AS
16 BEGIN
17
18 DECLARE @commandText VARCHAR(8000) -- 主语句
19 DECLARE @TopN INT -- 获取前几条记录
20 DECLARE @PageCount INT -- 总共会是几页
21 DECLARE @TopLimit INT -- 获取多少条记录
22 DECLARE @SQLRowCount NVARCHAR(4000) -- 用于查询记录总数的语句
23 DECLARE @SQLOrder VARCHAR(400) -- 排序类型
24 DECLARE @SQLTemp VARCHAR(4000) -- 临时变量
25
26 SET @SortExpression = LTRIM(RTRIM(@SortExpression))
27 SET @SortDire = UPPER(LTRIM(RTRIM(@SortDire)))
28
29 -- 这里是计算整体记录行数
30 IF @RecordCount IS NULL
31 BEGIN
32 IF @WhereConditional != ''
33 BEGIN
34 SET @SQLRowCount = 'SELECT @RecordCount=COUNT(1) FROM ' + @TableName + ' WHERE ' + @WhereConditional
35 END
36 ELSE
37 BEGIN
38 SET @SQLRowCount = 'SELECT @RecordCount=COUNT(1) FROM ' + @TableName
39 END
40 END
41
42 -- SELECT @RecordCount=@@ROWCOUNT
43 EXEC sp_executesql @SQLRowCount, N'@RecordCount INT OUT', @RecordCount out
44
45 IF @RecordCount IS NULL
46 BEGIN
47 SET @RecordCount = 0
48 END
49
50 -- 这里是控制页数最多少
51 SET @PageCount = @RecordCount / @PageSize + 1
52
53 -- 这里检查当前页的有效性
54 IF (@PageIndex < 1)
55 BEGIN
56 SET @PageIndex = 1
57 END
58
59 -- 这里限制最后一页的有效性
60 IF (@PageIndex > @PageCount)
61 BEGIN
62 SET @PageIndex = @PageCount
63 END
64
65 IF @SortDire != 'ASC'
66 BEGIN
67 SET @SQLTemp = '<(SELECT MIN'
68 SET @SQLOrder = ' ORDER BY ' + @SortExpression + ' DESC'
69 END
70 ELSE
71 BEGIN
72 set @SQLTemp = '>(SELECT MAX'
73 set @SQLOrder = ' ORDER BY ' + @SortExpression + ' ASC'
74 END
75
76 -- 这里是调试信息
77 -- SELECT @SQLOrder
78
79 -- 获取几条数据? 吉日嘎拉 2010-11-02 更新
80 SET @TopN = @RecordCount - @PageSize * (@PageIndex - 1)
81 IF @TopN > @PageSize
82 BEGIN
83 SET @TopN = @PageSize
84 END
85
86 SET @TopLimit = @PageSize * (@PageIndex - 1)
87 IF @TopLimit > @RecordCount
88 BEGIN
89 SET @TopLimit = @RecordCount
90 END
91
92 SET @commandText = 'SELECT TOP ' + STR(@TopN) + ' ' + @SelectField + ' FROM '
93 + @TableName + ' WHERE ' + @SortExpression + @SQLTemp + '('
94 + RIGHT(@SortExpression, LEN(@SortExpression) - CHARINDEX('.', @SortExpression)) + ') FROM (SELECT TOP ' + STR(@TopLimit)
95 + ' ' + @SortExpression + ' FROM ' + @TableName + @SQLOrder + ') AS TableTemp)'
96 + @SQLOrder
97
98 IF @WhereConditional != ''
99 SET @commandText = 'SELECT TOP ' + STR(@TopN) + ' ' + @SelectField + ' FROM '
100 + @TableName + ' WHERE ' + @SortExpression + @SQLTemp + '('
101 + RIGHT(@SortExpression, LEN(@SortExpression) - CHARINDEX('.',@SortExpression)) + ') FROM (SELECT TOP ' + STR(@TopLimit)
102 + ' ' + @SortExpression + ' FROM ' + @TableName + ' WHERE ' + @WhereConditional + ' '
103 + @SQLOrder + ') AS TableTemp) AND ' + @WhereConditional + ' ' + @SQLOrder
104
105 IF @PageIndex = 1
106 BEGIN
107 -- 第一页的显示效率提高
108 SET @SQLTemp = ''
109 IF @WhereConditional != ''
110 SET @SQLTemp = ' WHERE ' + @WhereConditional
111
112 SET @commandText = 'SELECT TOP ' + STR(@TopN) + ' ' + @SelectField
113 + ' FROM ' + @TableName + @SQLTemp + ' ' + @SQLOrder
114 END
115 ELSE
116 BEGIN
117 -- 解决大数据最有一页卡死的问题
118 IF @PageIndex = @PageCount
119 BEGIN
120 IF @SortDire = 'ASC'
121 BEGIN
122 SET @SQLOrder = ' ORDER BY ' + @SortExpression + ' DESC'
123 END
124 ELSE
125 BEGIN
126 SET @SQLOrder = ' ORDER BY ' + @SortExpression + ' ASC'
127 END
128
129 SET @SQLTemp = ''
130 IF @WhereConditional != ''
131 SET @SQLTemp = ' WHERE ' + @WhereConditional
132
133 SET @commandText = 'SELECT TOP ' + STR(@TopN) + ' ' + @SelectField
134 + ' FROM ' + @TableName + @SQLTemp + ' ' + @SQLOrder
135
136 SET @commandText = 'SELECT ' + @SelectField
137 + ' FROM (' + @commandText + ') AS TableTemp ORDER BY ' + @SortExpression + ' ' + @SortDire
138 END
139 END
140
141 EXEC (@commandText)
142
143 -- 这个是调试程序用的
144 -- SELECT @commandText
145
146 END
原文地址:https://www.cnblogs.com/lihuijun/p/2419792.html