性能调优SQL

性能调优SQL,sql,sql-server,sql-server-2012,Sql,Sql Server,Sql Server 2012,我有以下sql语句。当我检查这个查询的执行计划时,我们观察到一个索引扫描。如何用索引搜索替换它。我在IdDeleted列上有非聚集索引 我试着这样做,得到了索引搜索,但结果是错误的 SELECT Cast(Format(Sum(COALESCE(InstalledSubtotal, 0)), 'F') AS MONEY) AS TotalSoldNet, BP.BoundProjectId

我有以下sql语句。当我检查这个查询的执行计划时,我们观察到一个索引扫描。如何用索引搜索替换它。我在IdDeleted列上有非聚集索引

我试着这样做,得到了索引搜索,但结果是错误的

SELECT Cast(Format(Sum(COALESCE(InstalledSubtotal, 0)), 'F') AS MONEY) AS TotalSoldNet,
       BP.BoundProjectId                                               AS ProjectId
FROM   BoundProducts BP
WHERE  BP.IsDeleted=0
GROUP  BY BP.BoundProjectId 
任何人都可以建议我使用index seek获得正确的结果集

我的意思是如何替换(BP.IsDeleted=0或BP.IsDeleted为null)条件以使用索引查找

编辑、添加其中一个答案的注释中的行数:

null: 254962 rows
0:    392002 rows
1:     50211 rows

你一辈子都试过工会吗? 选择。。。 其中isdeleted=0 联合所有 选择。。。 其中isdeleted为空

或者可以添加查询提示(索引=[indexname])


还要注意,基数将决定SQL是使用搜索还是扫描搜索,搜索速度更快,但如果索引没有覆盖所需的所有列,则可能需要进行键查找。一个很好的经验法则是,如果查询将返回表的5%以上,那么SQL将倾向于扫描。

您不会得到索引查找,因为您要获取表中几乎93%的行,在这种情况下,只扫描整个索引更快、更便宜

如果存在性能问题,则应考虑删除format()-函数,尤其是在查询返回大量行时。阅读


其他选项可能是创建索引视图并预聚合数据。这当然增加了一个更新/插入操作的开销,所以只考虑这是经常做的,而不是经常更新表。

一个可能性是,两个查询,每个条件一个,和代码>联合< /代码>它们。together@HoneyBadger可能不是最好的选择,因为你要扫描两次表,所以在试图智取数据库引擎时一定要小心。如果它选择了索引扫描而不是索引查找,那是因为它比较了两者的成本,并确定在这种情况下,对您试图获取的数据使用查找不会有任何好处。你有任何理由怀疑它的正确性吗?扫描可以优于搜索,尤其是在较小的集合上,其中有大量行与is null谓词相匹配,使用
ISNULL(BP.IsDeleted,0)
将始终阻止索引搜索。您的第一个建议将导致查询扫描表两次,正如@RaduGheorghiu在注释中提到的那样。如果表太大的话,这在性能上会很昂贵。我读过一些帖子,上面说这个经验法则只适用于10%或更多。另外,我也读过一些帖子,上面说这个百分比没有“神奇数字”。我倾向于认为没有神奇的数字,因为它将全部由查询成本决定。而且成本比行数更复杂。是的,基数很重要,但它不是唯一的因素。@John:我的桌子每天都在增长。目前,该表包含50万条记录。我预计大约有200万或300万。@James:“null”=254962行,“0”=392002行,“1”=50211行
null: 254962 rows
0:    392002 rows
1:     50211 rows