2011-01-20 52 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

  • 内嵌表的功能扩展到主查询(它们就像看法宏)
  • 标(你一个)和多语句表函数不和的黑箱到“外”查询