MSSQL 2005 分页分析及优化
MSSQL 分頁(yè)方式說明:
目前我所知的有以下幾種方式
- 臨時(shí)表
- 表變量
- in, not in
- SET ROWCOUNT
- CTE
- id >, id <
優(yōu)缺點(diǎn)分析: 性能最低, 可操作性差
第一種方式和第二種方實(shí)際上是比較類似的.
優(yōu)點(diǎn): 排序方式比較隨意
缺點(diǎn):
第一種方式 有大量的 IO 開銷.
第二種方式則會(huì)開銷內(nèi)存, 但當(dāng)表數(shù)據(jù)量比較大的時(shí)候性能會(huì)直線下降.
所以這兩種方式都不適合做大數(shù)據(jù)量的分頁(yè).
第三種方式: 性能次之, 可操作較差
優(yōu)點(diǎn): 排序方式比較隨意
缺點(diǎn): 資源開銷比較大, 數(shù)據(jù)庫(kù)會(huì)承擔(dān)不小的運(yùn)算壓力, 所以也不適合做大表分頁(yè).
第四種方式: 性能平均, 可操作性尚可
優(yōu)點(diǎn): 排序相對(duì)比較隨意, 各分頁(yè)情況下速度平均, 屬于不是最快也不是最慢.
缺點(diǎn): 沒有明顯缺點(diǎn).
第五種方式: 性能較好, 可操作性良好
優(yōu)點(diǎn): 排序相對(duì)比較隨意, 代碼簡(jiǎn)潔, 適用面廣.
缺點(diǎn): 尾頁(yè)速度比較慢(需針對(duì)優(yōu)化).
第六種方式: 性能最好, 可操作性比較差
優(yōu)點(diǎn): 速度快.
缺點(diǎn): 尾頁(yè)速度比較慢(需針對(duì)優(yōu)化), 對(duì)排序鍵有要求.
PS: 以上內(nèi)容居于以前測(cè)試結(jié)果說得.
測(cè)試用庫(kù) DB_PagingTest, 測(cè)試用表: Paing_New
主鍵: ID Desc
總記錄 @RecordCount: 10000331
分頁(yè)尺寸 @PageSize: 30
總頁(yè)數(shù) @PageCount: 333345
請(qǐng)求頁(yè) @AbsolutePage
分頁(yè)情況分析:
- @AbsolutePage == 1
- @AbsolutePage < @PageCount/2
- @AbsolutePage >= @PageCount/2
- @AbsolutePage == @PageCount
情況 1:
請(qǐng)求頁(yè)等于第一頁(yè), 這種情況是最簡(jiǎn)單的.
代碼:
Select TOP @PageSize * From [Paing_New] Order BY ID Desc情況 2:
請(qǐng)求頁(yè)小于總頁(yè)數(shù)/2
代碼:
? ? WITH CTE AS
? ? (
? ?? ?SELECT TOP @AbsolutePage * @PageSize
? ?? ?*
? ?? ?ROW_NUMBER() Over (Order By ID Desc) as _RowNumber
? ?? ?FROM [Paing_New]
? ? )
? ? SELECT
? ?? ?*
? ? FROM CTE
? ? WHERE _RowNumber > (@AbsolutePage - 1) * @PageSize);
情況 3:
請(qǐng)求頁(yè)大于等于總頁(yè)數(shù)/2
理論上 請(qǐng)求頁(yè)等于總頁(yè)數(shù)/2的時(shí)候應(yīng)該也有優(yōu)化方法.
代碼:
? ? WITH CTE AS
? ? (
? ?? ?SELECT TOP @RecordCount - (@AbsolutePage - 1) * @PageSize
? ?? ?*,
? ?? ?ROW_NUMBER() Over (Order BY ID Asc) as _RowNumber
? ?? ?FROM [Paing_New]??
? ? )
? ? SELECT
? ?? ?*
? ? FROM CTE
? ? WHERE _RowNumber > (@RecordCount - @AbsolutePage * @PageSize) Order BY ID Desc;
情況 4:
請(qǐng)求頁(yè)等于總頁(yè)數(shù)
代碼:
? ? WITH CTE AS
? ? (
? ?? ?SELECT TOP @RecordCount - (@AbsolutePage - 1) * @PageSize
? ?? ?*,
? ?? ?ROW_NUMBER() Over (Order BY ID Asc) as _RowNumber
? ?? ?FROM [Paing_New]??
? ? )
? ? SELECT
? ?? ?*
? ? FROM CTE Order BY ID Desc;
數(shù)據(jù)測(cè)試結(jié)果:
第 30 條, 即 1 頁(yè), CPU 時(shí)間 = 0 毫秒,占用時(shí)間 = 1 毫秒, 實(shí)際執(zhí)行時(shí)間 = 0 毫秒;
第 1W 條, 即 334 頁(yè), CPU 時(shí)間 = 0 毫秒,占用時(shí)間 = 3 毫秒, 實(shí)際執(zhí)行時(shí)間 = 0 毫秒;
第 10W 條, 即 3334 頁(yè), CPU 時(shí)間 = 31 毫秒,占用時(shí)間 = 26~28 毫秒, 實(shí)際執(zhí)行時(shí)間 = 16~33 毫秒;
第 100W 條, 即 3334 頁(yè), CPU 時(shí)間 = 250~260 毫秒,占用時(shí)間 = 250~260 毫秒, 實(shí)際執(zhí)行時(shí)間 = 250~260 毫秒;
第 5000130 條(中間頁(yè)), 即 166671 頁(yè), CPU 時(shí)間 = 1200~1300 毫秒,占用時(shí)間 = 1200~1300 毫秒, 實(shí)際執(zhí)行時(shí)間 = 1200~1300 毫秒;
第 5000160 條(中間頁(yè)), 即 166672 頁(yè), CPU 時(shí)間 = 3400~3600 毫秒,占用時(shí)間 = 3400~3600 毫秒, 實(shí)際執(zhí)行時(shí)間 = 3400~3600 毫秒;
第 9000331 條, 即 300012 頁(yè), CPU 時(shí)間 = 266~281 毫秒,占用時(shí)間 = 273~285 毫秒, 實(shí)際執(zhí)行時(shí)間 = 266~296 毫秒;
第 9900331 條, 即 330012 頁(yè), CPU 時(shí)間 = 31~32 毫秒,占用時(shí)間 = 29~30 毫秒, 實(shí)際執(zhí)行時(shí)間 = 30~33 毫秒;
第 9999331 條, 即 333312 頁(yè), CPU 時(shí)間 = 0 毫秒,占用時(shí)間 = 2~3 毫秒, 實(shí)際執(zhí)行時(shí)間 = 0 毫秒;
第 10000331 條(尾頁(yè)), 即 333345 頁(yè), CPU 時(shí)間 = 0 毫秒,占用時(shí)間 = 1 毫秒, 實(shí)際執(zhí)行時(shí)間 = 0 毫秒;
PS: 關(guān)于時(shí)間的說明, CPU 時(shí)間和占用時(shí)間為 MSSQL 的統(tǒng)計(jì)結(jié)果, 實(shí)行時(shí)間是人為技術(shù)所得;
分頁(yè)方案優(yōu)點(diǎn):
對(duì)分頁(yè)多數(shù)情況進(jìn)行了針對(duì)優(yōu)化, 并且可以對(duì)非主鍵和順序編號(hào)等情況進(jìn)行分頁(yè).
開始和結(jié)尾速度都非常快, 因?yàn)檫x擇的記錄集相對(duì)較少.
分頁(yè)方案缺點(diǎn):
請(qǐng)求頁(yè)在總頁(yè)數(shù)中間的時(shí)候速度比較慢.
結(jié)論:
對(duì)于使用 ID 為主鍵索引的分頁(yè), 還是使用傳統(tǒng)的 ID 大于或小于這種方式最好.
對(duì)于分頁(yè)主鍵不明確的, 使用 CTE 的方式比較好
轉(zhuǎn)載于:https://www.cnblogs.com/qanholas/archive/2012/01/06/2314230.html
總結(jié)
以上是生活随笔為你收集整理的MSSQL 2005 分页分析及优化的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: tikz包 安装_LaTeX安装宏包
- 下一篇: sql 数据库 实例删除