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

时间:2019-01-28 20:33:51

标签: sql-server tsql sql-execution-plan

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

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

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

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

虽然返回的记录数有些不同,但我不认为这会造成如此大的影响。当我检查执行计划时,它表明根据我传递的值,它使用了不同的索引。更快的查询使用聚簇索引,而较慢的查询使用非聚簇索引。请参阅以下图片,以了解我的意思。

Slow

Fast

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

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

谢谢!

2 个答案:

答案 0 :(得分: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)运行这些统计信息,以查看重新编译是否有所改善(这不是永久解决方案,但将有助于进行故障排除)。

答案 1 :(得分:0)

两个使用相同谓词命中相同子查询的查询不必使用相同的执行计划。数据库背后的引擎旨在根据在表上提供的统计信息来更改其获取数据的方法。使用视图的方式绝对会影响查询的性能,因为如果对从视图内部拉出的值使用where子句,则该查询基本上是一个子查询,可能会在您遇到麻烦的地方让它了解要命中哪个索引,或者您可能对Qty + Statflag索引中包含的列有点满意。查询功能存在稳定性问题,可以重用相同的执行计划,而已更改的where子句是一个红色鲱鱼修改,只是使其尝试拉出新计划而失败。

如果[工作中心]就像是埋在视图中的主键或其他可搜索列,而这是您希望的主要查找谓词,则最好将该表放在视图之外,并将where子句放在该表中查询主体,然后将其内部连接到视图。