给出以下查询(注意SELECT pKey
子查询是在代码中动态生成的,因此是子查询的原因):
SELECT COUNT(p.pKey) AS [Value] FROM (
SELECT pKey
FROM [Profile] LEFT OUTER JOIN [Groups] ON gKey = pgKey
WHERE gName = 'Acme' AND pSearch04 = 'ACTIVE'
) p LEFT JOIN(SELECT dlpKey FROM DataLoads WHERE dlprocKey = 60909) d ON p.pKey = d.dlpKey
WHERE d.dlpKey IS NULL
我在同一个'上得到了非常不同的查询计划。数据库(虽然不同的SQL Server版本)。
在一个数据中心,我们有Microsoft SQL Server 2008 R2(SP2) - 10.50.4000.0。在另一台服务器中,我们有Microsoft SQL Server 2012(SP2-GDR)(KB3194719) - 11.0.5388.0(X64)。 2008年的评分为90,而2012年的评分为110.该查询产生了不同的计划,2012年表扫描(超时),2008年似乎使用现有指数(立即返回)。
2012年计划还建议创建一个指数将产生98%的影响,而2008年则没有这样的建议。注意,我并不是真的想建立一个索引(在pSearch04字段上),因为我们的数据库是一个多租户数据库,而pSearch04可能是客户端之间完全不同的数据。
我使用Red Gate SQL Compare来比较模式,它说它们是“相同的”(用户只有几个小差异)。
我尝试查看2008服务器上已保存的计划,并被告知要比较CardinalityEstimatorModelVersion属性和/或尝试计划比较选项 - 我在我的SSMS版本中都没有。
关于我如何进行调试的任何建议,看看为什么2012年似乎生成了一个使用表扫描的执行计划?我有限的SQL DBA技能不知所措。检查对其进行表扫描的表,索引和关系是相同的(通过手动比较与仅使用Red Gate)。
2008执行计划:https://pastebin.com/zgUTNy2q
2012年执行计划:https://pastebin.com/ab2qf5ut
如果有任何其他信息可以帮我解决,请告诉我。