cro*_*sek 3 sql-server execution-plan cardinality-estimates query-performance
以下查询在约 60 个数据库上并行运行。在没有提示的情况下,至少 10% 的数据库存在大量溢出和非最佳计划。
使用更大的数据库作为指导,查询被锁定并带有提示(1 个 CPU 上约 75 毫秒),以减少运行时的差异,因为 1 个错误的计划会导致整体运行时间终止。我们主要反对让每个DB自由调整其计划,因为从长远来看,某些DB可能会在生产平台上着火。我们对大型数据库的近乎最佳计划感到非常满意,但对于较小的数据库可能不是最佳的。
即使在添加带有完整扫描的统计信息后,一些(~5)较小的数据库仍然表现出小的 1 级溢出(参见计划)。运行时间仍然可以(125 毫秒),但希望消除溢出。
这是 Sql Server 2019。自适应授权功能 (2017) 是否应该因溢出而调整授权?在 SSMS 和查看计划中重复运行它似乎表明没有变化。
select top (@pMax)
aig.ObjectId,
iif((@pA in (1, 2, 3, 4, 5, 6, 9, 11, 12) and ttm.ObjectId is not null) or
(@pA in (7, 8, 10, 13, 14, 15)), 1.0, 0.0) as Rank
from oav.value aig
inner merge join Pub.CachedObjectHierarchyAttributes coha
on coha.ObjectId = aig.ObjectId
and coha.IsActiveForPublisher = 1
and coha.IsToolItem = 1
inner merge join Oav.ValueArray v897
on v897.PropertyId = 897
and v897.ObjectId = aig.ObjectId
and v897.[Value] = @pBrandId
left hash join oav.valuearray ttm
on ttm.ObjectId = aig.ObjectId
and ttm.PropertyId = 11131
and ttm.[Value] = @pToolTypeMapId
where aig.PropertyId = 2573
and aig.[Value] = @pA
order by ttm.[Value] desc -- to put TTM matches at the top
option (maxdop 1); -- limit to 1 cpu since it runs across all pubs
Run Code Online (Sandbox Code Playgroud)
来自 3 个索引的行估计会在实际行的 <1% 范围内寻找正确的匹配项。
然而,对两个最右边的搜索的第一次合并的估计有很大偏差,然后继续进行,导致溢出。通过前两个阶段的完美估计,还有哪些因素会影响该估计?
泄漏细节:
如果您已经在向查询中添加大量提示并且不想在这种情况下给 SQL Server 一个选择,那么我倾向于添加一个MIN_GRANT_PERCENT提示来消除溢出。查询计划只有两个消耗内存的操作,因此该类型的提示可能在这里有效。
当前的内存授予看起来相当小 - 也许 3 MB?相反,将其设置为 30 MB 不太可能会导致问题,对吧?在某些情况下,追踪并解决此类基数估计问题可能需要几个小时。您甚至可能需要几个小时才能收集并匿名化某人尝试回答您所提出的问题所需的所有信息。真的值得花时间这样做吗?