[SQL SERVER][Performance]排序效能問題
今天論壇上看到網友詢問排序效能問題,問題我大概簡述如下
Q:為什麼查詢使用 uidLogId排序速度很快,但改用dtDateTime DESC排序速度卻慢了10幾秒
(發問者就算針對 dtDateTime 建立索引後,速度也沒得到明顯提升)。
A:不知道大家有看出問題了嗎?我這裡先大概模擬發問者環境,
等大家看完整各測試過程,我相信你也會知道問題關鍵點在那裡~
先建立相關索引
Clustered Index
Nonclustered index(LogDate)
執行查詢(使用 pk_ap_log Asc排序)
select top(50) *
from
(
select ROW_NUMBER() over(order by ApLogId ) as 'row',*
from dbo.AP_LOG t1
) A
where row >(35000-1)*5
CPU時間(ms)=125。經過時間(ms)=300。
執行計畫
整體成本:0.0179884。
執行查詢(使用 LogDate Desc排序)
select top(50) *
from
(
select ROW_NUMBER() over(order by LogDate desc) as 'row',*
from dbo.AP_LOG t1
) A
where row >(35000-1)*5
CPU時間(ms)=140。經過時間(ms)=247。
執行計畫
整體成本:0.0180751。
結果比較表
CPU時間(ms) |
經過時間(ms) |
|
pk_ap_log Asc排序 |
125 |
300 |
LogDate Desc排序 |
140 |
247 |
結論:
不用懷疑你看到的效能結果,我的模擬環境中使用 LogDate Desc排序反而有較好的查詢效能,
這是為什麼呢? 主要是因為 Clustered 和 Nonclustered Index的差別,
發問者的SQL是查詢所有欄位,但發問者所建立的Nonclustered Index卻沒有包含其他欄位鍵值,
造成查詢時,無法有效利用該索引鍵值找到其他欄位資料位置(很典型的索引設計不佳),
至於索引設計和概念以及效能調效應該了解的基本知識這裡我就不多說了(可參考我底下連結),
最後!我補貼該Nonclustered Index其他部分和語法。
create nonclustered index nix_logdate
on dbo.AP_LOG(LogDate desc)
include(.....)
參考