基于WHERE值的不同SQL执行计划

问题描述 投票:0回答:2

我有一个稍微复杂的SQL视图,根据传递给WHERE子句的值执行不同的操作,我无法解释原因。

当我查询视图时,我有一个WHERE子句,它可以是两个值之一。根据使用的值,查询以不同的速度返回。

WHERE [Work Center] LIKE '2MSTMP' (returns 84 records in 2 seconds)

要么

WHERE [Work Center] =  '2ZLSR' (returns 504 records in 15 seconds)

虽然返回的记录数量略有不同,但我无法相信这会造成这么大的放缓。当我检查执行计划时,它表明根据我传递的值,它使用了不同的索引。更快的查询使用Clustered索引,而较慢的查询使用NonClustered索引。请参阅下面的图片,了解我的意思。

Slow

Fast

WHERE子句中使用的字段定义为varchar(8)。作为测试,我在WHERE子句中将两个值都转换为该数据类型(如果它在推断某些内容),但这没有任何效果。

谁能给我一些关于如何进一步研究的想法?我真的希望两个查询以相同(更快)的速度执行,但我不知道还有什么要检查。

谢谢!

sql-server tsql sql-execution-plan
2个回答
0
投票

你发布的内容不足以提供一个很好的答案,但这是我从屏幕截图中观察到的明显问题。

慢查询读取1,226,605行;慢查询只读170行。

第一个查询的谓词是:

WHERE STATUS_FLAG = 'A' OR STATUS_FLAG = 'R'

第二个的谓词是:

WHERE Qty_to_mfg > 0 AND (STATUS_FLAG = 'A' OR STATUS_FLAG = 'R')

也许将这个^^ WHERE Qty_to_mfg > 0添加到较慢的查询将有所帮助。

另请注意,WHERE [Work Center] LIKE '2MSTMP'WHERE [Work Center] = '2MSTMP'相同

最后 - 在每种情况下,两个查询中的基数估计都是偏离的。这是错误统计信息,联接/过滤器中使用的错误数据类型或参数嗅探的标志。考虑检查您的统计数据并考虑使用OPTION(RECOMPILE)运行它们以查看重新编译是否能改进(这不是一个永久的解决方案,但有助于排除故障)。


0
投票

使用相同谓词命中同一子查询的两个查询不必使用相同的执行计划。数据库背后的引擎旨在根据表中给出的统计信息更改获取数据的方法。如何使用视图绝对会影响查询的性能,你不能将其排除在外,因为如果你在视图中使用了一个where子句,那么这基本上是一个子查询,可能是你遇到麻烦的地方让它了解要击中哪个索引,或者你可能对Qty + Statflag索引中包含的列感到满意。有一个稳定性问题,查询能够重用相同的执行计划,更改的where子句是一个红色鲱鱼修改,只是让它试图拉出一个新的计划并失败。

如果[工作中心]就像一个隐藏在视图中的主键或其他可搜索列,并且这是您想要的主要搜索谓词,那么最好将该表放在视图之外,并将where子句放在该表的主体中。查询然后内部连接到视图。

© www.soinside.com 2019 - 2024. All rights reserved.