2011-01-20 88 views
6

任何人都可以幫助我理解以下查詢的SQL Server執行計劃嗎?SQL Server標量函數與子查詢執行計劃分析

我預計子查詢版本(查詢2)執行得更快,因爲它是基於集合的。這似乎捉迷藏獨立的查詢時是這樣 - 輕微 - 但是執行計劃顯示查詢費用爲15%對85%:缺少什麼我在這裏

//-- Query 1 (15%) - Scalar Function 
SELECT 
    gi.GalleryImageId, 
    gi.FbUserId, 
    dbo.GetGalleryImageVotesByGalleryImageId(gi.GalleryImageId) AS Votes 
FROM 
    GalleryImage gi 

//-- Query 2 (85%) - Subquery 
SELECT 
    gi.GalleryImageId, 
    gi.FbUserId, 
    (SELECT COUNT(*) FROM GalleryImageVote WHERE GalleryImageId = gi.GalleryImageId) 
FROM 
    GalleryImage gi 

;執行計劃是否會跳過該函數的成本?此外,有關上述任一方面是否可以更好地使用CTE或OVER/PARTITION查詢的建議?

預先感謝您!

+0

你有沒有他們在同一個查詢編輯器窗口?因爲查詢分析器會比較它們併爲每個窗口(15%/ 85%)分配一個相對值。 – JNK 2011-01-20 17:48:49

+0

是的,這就是%值來自於的地方:) – Robarondaz 2011-01-21 09:23:42

+0

查詢執行時間並不總是等於成本。 SQL Server似乎對CPU和RAM的使用比硬盤讀取更重要。 – jahu 2015-08-19 11:33:21

回答

6

永遠不要相信執行計劃。 這是一個非常有用的,讓你看到的計劃是什麼,但如果你想真正的指標,總是反過來統計

set statistics io on 
set statistics time on 

..和比較實際的執行。統計數據可能會說預期是15%/ 85%,但實際情況會告訴你真正轉化爲什麼。

性能調整沒有銀彈。隨着數據的形狀或分佈發生變化,即使是「最佳」查詢也會隨着時間而變化。

CTE不會有太大的不同,我不知道你打算如何做一個PARTITION查詢,但你可以試試left join表格。

SELECT 
    gi.GalleryImageId, 
    gi.FbUserId, 
    count(v.GalleryImageId) AS Votes 
FROM 
    GalleryImage gi 
    LEFT JOIN GalleryImageVote v ON v.GalleryImageId = gi.GalleryImageId 
GROUP BY 
    gi.GalleryImageId, gi.FbUserId 
4

優化器不知道函數的成本。

可以看到CPU和讀取,並通過探查雖然

一些相關的答案,從類似的問題持續。 OneTwo

  • 內嵌表的功能擴展到主查詢(它們就像看法宏)
  • 標(你一個)和多語句表函數不和的黑箱到「外」查詢