将常规列转换为持久计算列会导致此查询无法执行索引查找。为什么?
在多个 SQL Server 版本上进行了测试,包括 2016 SP1 CU1。
问题在于table1
, col7
。
表和查询是原始版本的部分(和简化)版本。我知道查询可以用不同的方式重写,并且出于某种原因避免了这个问题,但我们需要避免接触代码,为什么table1
不能被搜索的问题仍然存在。
正如 Paul White 所展示的(谢谢!),如果强制执行,则搜索可用,所以问题是:为什么优化器不选择搜索,以及我们是否可以做一些不同的事情来使搜索按预期进行,而无需更改代码?
为了澄清有问题的部分,这是错误执行计划中的相关扫描:
存储过程查询有时会在其中一个表上的统计信息更新后得到一个糟糕的计划,但之后可以立即重新编译为好的计划。相同的编译参数。
问题似乎来自在 SP 中创建然后加入的一个小临时表。错误的计划在临时表上有一个警告,即连接列没有统计信息。是什么赋予了?
SQL Server 2016 SP1 CU4,具有 2014 兼容级别
糟糕的计划:
好计划:
USE AppDB
GO
SET QUOTED_IDENTIFIER ON
SET ANSI_NULLS ON
GO
CREATE PROCEDURE [MySchema].[MySP]
@MyId VARCHAR(50),
@Months INT
AS
BEGIN
SET NOCOUNT ON
SELECT *
INTO #MyTemp
FROM AppDB.MySchema.View_Feeder vf WITH (NOLOCK)
WHERE vf.MyId = @MyId AND vf.Status IS NOT NULL
SELECT wd.Col1
, vp.Col2
, vp.Col3
FROM AppDB.MySchema.View_VP vp WITH (FORCESEEK)
INNER JOIN #MyTemp wd ON wd.Col1 = vp.Col1
WHERE vp.Col3 > DATEADD(MONTH, @Months * -1, …
Run Code Online (Sandbox Code Playgroud) sql-server optimization statistics execution-plan temporary-tables