相关疑难解决方法(0)

恒定扫描假脱机

我有一张有几十行的桌子。简化设置如下

CREATE TABLE #data ([Id] int, [Status] int);

INSERT INTO #data
VALUES (100, 1), (101, 2), (102, 3), (103, 2);
Run Code Online (Sandbox Code Playgroud)

我有一个查询将这个表连接到一组表值构造的行(由变量和常量组成),比如

DECLARE @id1 int = 101, @id2 int = 105;

SELECT
    COALESCE(p.[Code], 'X') AS [Code],
    COALESCE(d.[Status], 0) AS [Status]
FROM (VALUES
        (@id1, 'A'),
        (@id2, 'B')
    ) p([Id], [Code])
    FULL JOIN #data d ON d.[Id] = p.[Id];
Run Code Online (Sandbox Code Playgroud)

查询执行计划显示优化器的决定是使用FULL LOOP JOIN策略,这似乎是合适的,因为两个输入都有很少的行。但是,我注意到(并且不能同意)的一件事是正在假脱机的 TVC 行(请参阅红色框中的执行计划区域)。

恒定扫描假脱机

为什么优化器在这里引入spool,这样做的原因是什么?除了线轴没有什么复杂的。看起来是没有必要的。在这种情况下如何摆脱它,可能的方法是什么?


上述计划获得于

Microsoft SQL Server 2014 (SP2-CU11) (KB4077063) - 12.0.5579.0 (X64)

sql-server execution-plan

14
推荐指数
1
解决办法
1100
查看次数

恒定扫描加入

在准备我之前的Constant Scan 问题时,我VALUES以各种方式进行了试验,并遇到了关于连接的事情,VALUES这对我来说很奇怪。

设置很简单

CREATE TABLE #data ([Id] int);
INSERT INTO #data VALUES (101), (103);
Run Code Online (Sandbox Code Playgroud)

然后有一个查询

DECLARE @id1 int = 101, @id2 int = 102;

SELECT *
FROM (VALUES (@id1), (@id2)) p([Id])
    FULL HASH JOIN #data d ON d.[Id] = p.[Id];
Run Code Online (Sandbox Code Playgroud)

没有什么特别之处。如果你运行它,它会工作并产生它的结果。这是它的执行计划

恒扫描加盟计划

VALUES然而删除行

SELECT *
FROM (VALUES (@id1)) p([Id])
    FULL HASH JOIN #data d ON d.[Id] = p.[Id];
Run Code Online (Sandbox Code Playgroud)

导致优化器失败

消息 8622,级别 16,状态 1,第 1 行
查询处理器无法生成查询计划...

为什么?有没有办法(除了将参数放入临时表)使用哈希算法使其工作?

注意:这不是真正的设备,用于研究优化器行为和功能。


上面的例子在

Microsoft SQL …

sql-server optimization database-internals

5
推荐指数
1
解决办法
381
查看次数