我的查询是否存在参数嗅探性能问题?我保留了查询执行计划建议的非聚集索引,但我仍然怀疑这是参数嗅探还是其他问题。请检查以下查询:
declare @orgid int=22,
@salesperson int=0
select
pd.col1,dd.col1
from t1 pd
inner join (select max(doId) doid,personId from t2 where productId=99 and personId>0
and effectDate IS NOT NULL group by personId) d on pd.personId=d.personId
join t2 dd on d.doid=dd.doId
join (select max(requestId) requestid,doId from t3 group by doId ) p on dd.doId=p.doId
join t3 pp on p.requestid=pp.requestIdjoin person prn on cp.personId=prn.personId
where pd.organizationId=@orgId
and (@salesperson=0 or cp.personId=@salesperson)
order by pd.patientName
这条线会引起问题吗?
(@salesperson=0 or cp.personId=@salesperson)
没有
由于您没有任何参数,因此不存在参数嗅探问题。您使用的是局部变量,这意味着无论您使用哪个值,您始终都会得到相同的密度向量估计值。
您可能想看看这个问答:
嗅探与敏感度
了解参数嗅探通常是一件好事是有帮助的。人们经常对此持负面看法,而实际上他们遇到的问题是参数敏感性。
如果参数接触的数据严重偏向某些值而较少偏向其他值,那么共享这些查询计划可能会导致性能问题。
艾克斯胡尔
您遇到的真正问题是,您编写了一个万能查询,而 SQL Server 无法对其进行任何合理的处理。它无法查找索引,也无法很好地估计基数,这都是因为您在查询中写入了一个运行时决策:
(@salesperson=0 or cp.personId=@salesperson)
欲了解更多详情,请参阅我的帖子:
OPTION(RECOMPILE);
您可能会发现,如果在查询末尾添加,您会得到更好的计划。这将允许进行称为参数嵌入的优化。即使您使用的是局部变量,也适用相同的规则。如果您想要一个不需要在每次执行时重新编译的长期解决方案,您可能需要使用动态 SQL。
潜在的重写
如果您有良好的支持索引,您可能想尝试此版本的查询。您很快就会知道您的索引是否热门,但调整这些索引是另一个问题。
重要的
由于我上面使用的动态 SQL确实使用了参数,因此使用尽可能多常用的
@orgId
和值来测试性能非常重要。您实际上可能会遇到参数敏感性问题。@salesperson