相关疑难解决方法(0)

为什么这个查询不使用索引假脱机?

我问这个问题是为了更好地了解优化器的行为并了解索引假脱机的限制。假设我将 1 到 10000 之间的整数放入堆中:

CREATE TABLE X_10000 (ID INT NOT NULL);
truncate table X_10000;

INSERT INTO X_10000 WITH (TABLOCK)
SELECT TOP 10000 ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM master..spt_values t1
CROSS JOIN master..spt_values t2;
Run Code Online (Sandbox Code Playgroud)

并强制嵌套循环连接MAXDOP 1

SELECT *
FROM X_10000 a
INNER JOIN X_10000 b ON a.ID = b.ID
OPTION (LOOP JOIN, MAXDOP 1);
Run Code Online (Sandbox Code Playgroud)

这是对 SQL Server 采取的相当不友好的操作。当两个表都没有任何相关索引时,嵌套循环连接通常不是一个好的选择。这是计划:

错误查询

在我的机器上查询需要 13 秒,从 table spool 中提取了 100000000 行。但是,我不明白为什么查询必须很慢。查询优化器能够通过索引假脱机动态创建索引。这个查询似乎是索引假脱机的完美候选者。

以下查询返回与第一个相同的结果,具有索引假脱机,并且在不到一秒的时间内完成:

SELECT *
FROM X_10000 a
CROSS APPLY …
Run Code Online (Sandbox Code Playgroud)

sql-server optimization index-spool sql-server-2016

23
推荐指数
1
解决办法
2582
查看次数

CROSS APPLY 产生外连接

为了回答分区上不同的 SQL 计数, Erik Darling 发布了此代码以解决以下问题COUNT(DISTINCT) OVER ()

SELECT      *
FROM        #MyTable AS mt
CROSS APPLY (   SELECT COUNT(DISTINCT mt2.Col_B) AS dc
                FROM   #MyTable AS mt2
                WHERE  mt2.Col_A = mt.Col_A
                -- GROUP BY mt2.Col_A 
            ) AS ca;
Run Code Online (Sandbox Code Playgroud)

查询使用CROSS APPLY(not OUTER APPLY) 那么为什么在执行计划中有连接而不是连接?

在此处输入图片说明

另外,为什么取消注释 group by 子句会导致内部联接?

在此处输入图片说明

我不认为数据很重要,而是从 kevinwhat 在另一个问题上提供的数据中复制:

create table #MyTable (
Col_A varchar(5),
Col_B int
)

insert into #MyTable values ('A',1)
insert into #MyTable values ('A',1)
insert into …
Run Code Online (Sandbox Code Playgroud)

sql-server execution-plan cross-apply

18
推荐指数
1
解决办法
1959
查看次数