dtr*_*yan 3 sql-server execution-plan sql-server-2014
我在 SQL Server 2014 SP2 中有一个 T-SQL 存储过程,它在服务器上花费的时间是我在本地环境中花费的时间的 3 倍。
我将本地数据库恢复到服务器上的数据库,因此架构和数据是相同的。
我是一名程序员,并不是真正的 DBA,所以请耐心等待。
在您查看 XML 之前,执行计划似乎是相同的。在我的本地环境中,Stream Aggregate 用于其中一个查询以进行不同的选择,而在服务器上,它看起来像是 Sort 与散列一起使用。
服务器的处理器比我的(野兽)本地机器少的事实似乎导致了这个问题。每个查询在服务器上都需要更长的时间。这可能是在服务器上选择排序/散列而不是流聚合的原因吗?
有没有办法强制流聚合?
这是存储过程的 SQL:http : //pastebin.com/kkXM3Bsf
这是我本地环境的执行计划:http : //pastebin.com/0u7SHxnM
这是服务器的执行计划:http : //pastebin.com/9sE9DfM0
正如我在对相关问答的回答中所讨论的,硬件配置会影响计划选择:
这个问题没有量化“3x”性能差异,但假设它足够重要,需要关注:
USE PLAN提示完全强制计划的广泛形状。这将防止优化器随着时间的推移随着数据量和分布的变化选择不同的计划形状,因此定期审查强制计划很重要。FORCESEEK可以通过对应该通过查找(例如,由嵌套循环连接驱动)而不是扫描(使用散列或合并连接)访问的表的目标提示来更接近所需的计划形状。在您的情况下,FORCESEEK提示可以应用于Account和/或CustomerLocation。这可能比前一点中的强制整个计划形状更可取,因为它为计划的其他区域提供了优化器的自由度。@country is null or ca.Country = @country通过使用RECOMPILE提示或编写两个单独的查询(一个用于NULLcase;另一个用于 non- NULL)由IF @country IS NULL测试包围来为优化器提供更好的谓词机会。首先尝试两个单独的查询。您应该能够通过QUERYTRACEON (7470)提示避免排序溢出。这记录在:
修复:当估计的行数和行大小正确时,排序运算符会溢出到 SQL Server 2012 或 SQL Server 2014 中的 tempdb
没有支持的方法来强制 Stream Aggregate(通过 Sort Distinct),而不强制执行整个计划。
我首先将查询编写为两个备选方案(或者使用RECOMPILE提示,如果您可以容忍每次执行时重新编译),启用 7470 跟踪标志,然后从那里开始。计划强制将是我最不喜欢的选择。
如果服务器具有非常大的内存量,并且计划通常喜欢在不应该使用内存消耗的运算符时,您可以考虑使用 TF 2335测试您的整个工作负载,如链接的问答中所述。我会先尝试更有针对性的方法.
另请参阅我的文章:参数嗅探、嵌入和RECOMPILE选项