症状
使用多个行填充表变量,然后将其与其他表联接时,查询优化器可能会选择低效的查询计划,这可能会导致查询性能较慢。
解决方案
应用此修补程序后,你可以打开跟踪标记2453以允许表变量在行数足够更改时触发重新编译。 这可能允许查询优化器选择更高效的计划。 此问题首先已在 SQL Server 的以下累积更新或/和 Service Pack 中修复。
SQL Server 2014 的累积更新3 /en-us/help/2984923
SQL Server 的每个新的累积更新均包含以前的累积更新中包含的所有修补程序和所有安全修补程序。 查看 SQL Server 的最新累积更新:
Service Pack 具有累积性。 每个新 Service Pack 除了包含所有新修复程序外,还包含以前 Service Pack 中的所有修复程序。 我们建议为该服务包应用最新的服务包和最新的累积更新。 在安装最新的 Service Pack 之前,不需要安装以前的 Service Pack。 使用以下文章中的表1查找有关最新服务包和最新累积更新的详细信息:
更多信息
在批处理或过程中使用表变量时,查询将针对表变量的初始空状态进行编译和优化。 如果此表变量在运行时填充了许多行,则预编译的查询计划可能不再是最佳的。 例如,查询可以通过嵌套循环联接表变量,因为对于少量的行而言,它通常更高效。 如果表变量具有上百万行,则此查询计划可能会效率较低。 在这种情况下,哈希联接可能是更好的选择。 若要获取新的查询计划,需要重新编译它。 但是,与其他用户或临时表不同,表变量中的行数更改不会触发查询重新编译。 通常情况下,你可以使用选项(重新编译)来解决此种情况,该选项具有自己的开销成本。跟踪标记2453允许没有选项(重新编译)的查询重新编译带来的好处。 此跟踪标志不同于两个主要方面中的选项(重新编译)。(1)它使用与其他表相同的行计数阈值。 查询不需要针对每个执行进行编译,这与选项(重新编译)不同。 仅当行计数更改超过预定义阈值时才会触发重新编译。(2)选项(重新编译)强制查询查看参数并为其优化查询。 此跟踪标志不强制参数扫视。注意 此跟踪标志必须位于运行时。 不能将此跟踪标志与 QUERYTRACEON 配合使用。 必须小心使用此跟踪标志,因为它可以增加查询重新编译的次数,这可能会比更好地优化查询优化成本更多。
状态
Microsoft 已经确认这是一个列于“适用范围”部分的 Microsoft 产品问题。