哪个执行计划有更好的表现?

时间:2014-07-26 06:02:39

标签: sql-server performance database-performance sql-execution-plan

(我的英语不够好。所以忍受我)

我正在努力优化此查询:

Select Title from Groups Where GroupID = WWPMD.GroupID) as GroupName 
FROM         dbo.Detail AS WWPMD INNER JOIN
                  dbo.News AS WWPMN ON WWPMD.DetailID = WWPMN.NewsID
WHERE 
WWPMD.IsDeleted = 0 AND WWPMD.IsEnabled= 1 AND WWPMD.GroupID IN (
Select ModuleID FROM Page_Content_Item WHERE     ContentID='a6780e80-4ead4e62-9b22-1190bb88ed90')

在这种情况下,表在主键上具有GUID的聚簇索引。在执行计划中,箭头有点厚,并且聚集索引的成本寻求,对于表"细节"是87%,密钥查找没有成本

然后,我改变了表"细节"的索引。我已将聚集索引放在日期时间列上,并在PK和FK上放置3个非聚簇索引。现在在执行计划中,表格细节的索引搜索成本是4%,键查找是80%,带有细箭头。

我想知道哪个执行计划更好,我该怎么做才能改进此查询。

更新

感谢各位的指导。还有一个问题。我想知道聚集索引搜索的80%成本是否更好,或非聚集索引的80%总成本搜索和密钥查找。哪个更好?

4 个答案:

答案 0 :(得分:1)

IN语句适用于选择littele位数据如果选择更多数据,则应使用INNER JOIN,其性能优于IN,用于大数据

IN比DISTINCT

上的JOIN快

EXISTS比IN更有效,因为“EXISTS只返回一行”

答案 1 :(得分:0)

当你的guid不是顺序时,guid列上的聚簇索引不是一个好主意,因为这会导致插入时性能下降。表中的记录是基于聚簇索引进行物理排序的。聚集索引应放在具有连续值且不会(通常)更改的列上。

如果你在groupid(表组)上有非聚集索引,那么你可以将'title'作为该索引的包含列。有关包含的列,请参阅msdn。

答案 2 :(得分:0)

我建议使用以下查询:

INNER JOIN (SELECT DISTINCT ModuleID FROM Page_Content_Item WHERE ContentID='a6780e80-4ead4e62-9b22-1190bb88ed90')z OR WWPMD.GroupID= z.ModuleID

而不是:

AND WWPMD.GroupID IN (
   Select ModuleID FROM Page_Content_Item WHERE ContentID='a6780e80-4ead4e62-9b22-1190bb88ed90')

同样必须是此查询的调查执行计划,似乎带有过滤器(Detail.DetailId)的IsDeleted = 0 and IsEnable = 1上的索引非常有用。

答案 3 :(得分:0)

除非在JOIN和/或WHERE子句中指定最左侧的索引列,否则索引不会特别有用。我建议下面的索引(尽可能是唯一的):dbo.Detail(GroupID),dbo.News(DetailID),dbo.Page_Content_Item(ContentID)

您可以使用包含的列和/或过滤器对这些索引进行细分,但我怀疑如果没有这些措施,性能可能会很好。

请注意,主键很重要。这不仅是设计最佳实践,还会在关键列上自动创建唯一索引,这可以提高相关列上表的连接性能。请考虑查看您的模型,以确保您拥有正确的主键和关系。