DataGrid/GridView 內建分頁會一次撈回所有資料再切頁,資料量大時記憶體與回應時間急劇惡化。本文分析三種自訂分頁存儲程序(暫存表、動態 SQL、ROWCOUNT/升冪降冪),並提供效能測試結論與通用化建議。
aspnet_wp.exe 記憶體暴漲、GC 壓力大。CREATE TABLE #Temp (ID int IDENTITY PRIMARY KEY, PK int)
INSERT INTO #Temp SELECT PK FROM BigTable ORDER BY SortCol
SELECT * FROM BigTable JOIN #Temp ON BigTable.PK = #Temp.PK
WHERE ID BETWEEN @StartRow AND @EndRow
缺點:百萬筆資料建立百萬列暫存表,tempdb 壓力大,效能最差,已淘汰。
DECLARE @temp TABLE (PK int PRIMARY KEY)
INSERT INTO @temp
SELECT TOP @PageSize PK FROM (
SELECT TOP (@StartRow + @PageSize) PK, SortCol
FROM BigTable ORDER BY SortCol ASC
) t ORDER BY SortCol DESC
SELECT * FROM BigTable JOIN @temp ON BigTable.PK = @temp.PK
ORDER BY SortCol ASC
原理:子查詢正序取前 N 筆,外層倒序取最後 PageSize 筆,再正序輸出。適合中小資料量。
使用 SET ROWCOUNT @PageSize 配合動態 SQL 組裝 ORDER BY 子句,支援任意排序欄位。需確保排序欄位有索引,否則全表掃描極慢。
@SortColumn、@SortDir,以動態 SQL 組裝查詢。| 方法 | 首頁耗時 | 第 500 頁耗時 | 備註 |
|---|---|---|---|
| 暫存表 | 12.3 秒 | 14.8 秒 | tempdb 壓力大,不推薦 |
| 升冪降冪 | 0.45 秒 | 1.2 秒 | 中等資料量適用 |
| 動態 SQL + 索引 | 0.12 秒 | 0.15 秒 | 大資料量首選 |