[SQL SERVER][Performance]排序效能問題

[SQL SERVER][Performance]排序效能問題

今天論壇上看到網友詢問排序效能問題,問題我大概簡述如下

Q:為什麼查詢使用 uidLogId排序速度很快,但改用dtDateTime DESC排序速度卻慢了10幾秒

(發問者就算針對 dtDateTime  建立索引後,速度也沒得到明顯提升)。

 

A:不知道大家有看出問題了嗎?我這裡先大概模擬發問者環境,

等大家看完整各測試過程,我相信你也會知道問題關鍵點在那裡~

 

先建立相關索引

Clustered Index

image

 

Nonclustered index(LogDate)

image

 

執行查詢(使用 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

image

CPU時間(ms)=125。經過時間(ms)=300。

 

執行計畫

image

image

整體成本: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

image

CPU時間(ms)=140。經過時間(ms)=247。

 

執行計畫

image

image

整體成本: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(.....)

image

 

 

參考

[SQL SERVER][Memo]Clustered VS NonClustered Indexes

[SQL SERVER][Performance]查詢效能調校