SQL Server 如何确定查询计划的缺失索引建议中键列的顺序?
当第一个表中的连接列定义为 NOT NULL 并且对第二个表中的相应列具有受信任的外键约束时,SQL Server 查询优化器似乎不会将 OUTER JOIN 转换为 INNER JOIN。
在这种情况下,似乎可以将 OUTER JOIN 转换为等效的 INNER JOIN,因为第一个表中的每一行是:
例如,请考虑以下表格:
CREATE TABLE dbo.tbl_fk
(
fk_val CHAR(1) NOT NULL PRIMARY KEY CLUSTERED,
junk VARCHAR(100) NOT NULL
);
CREATE TABLE dbo.tbl_main
(
id INT NOT NULL PRIMARY KEY CLUSTERED IDENTITY(1,1),
fk_val CHAR(1) NOT NULL FOREIGN KEY REFERENCES dbo.tbl_fk(fk_val)
);
Run Code Online (Sandbox Code Playgroud)
在以下查询中,为什么优化器没有将执行计划中的 LEFT OUTER JOIN 转换为 INNER JOIN?
SELECT m.fk_val, f.junk
FROM dbo.tbl_main AS m
LEFT OUTER JOIN dbo.tbl_fk AS f
ON …Run Code Online (Sandbox Code Playgroud) 不久前,Brent Ozar 发表了一篇文章,详细介绍了 SQL Server 和 PostgreSQL 之间的一些差异:
SQL Server 和 PostgreSQL 的两个重要区别
第一点(“CTE 是优化栅栏”)引起了我的注意,因为很明显,在提供的示例中,SQL Server 将 CTE 和主查询组合在一起并将其优化为单个查询(而不是在PostgreSQL)。
但是,这种行为似乎与我在其他博客和培训课程中看到的示例相反,其中 SQL Server 确实将 CTE 视为优化栅栏,从而可以更好地使用索引、更好的性能等。例如:
因此,似乎 SQL Server 有时“尊重”CTE 作为优化栅栏。是否有任何好的资源可以记录 SQL Server 将可靠地将 CTE 作为优化栅栏(或相反的行为)的已知案例的特定列表?
SQL Server 2014 中是否存在任何已知的阻塞问题,这些问题特定于在初始表创建后在临时表上创建一个或多个筛选索引?(即不是内联索引创建)
我不允许发布实际代码;因此,我更改了表/列名称以保护无辜者。下面具有代表性但非常粗略的逻辑包含在存储过程的开头。
我相信,当存储过程同时运行多次时会发生阻塞。根据我的 DMV 查询,存储过程在第一个非聚集索引创建语句中被阻塞。
CREATE TABLE #temp_table_name_goes_here (
[the_first_col] BIGINT NULL
,[the_second_col] INT NULL
,[another_col] VARCHAR(20) NULL
);
CREATE INDEX tmp_indx_temp_table_name_goes_here_1 ON #temp_table_name_goes_here (the_first_col)
WHERE the_first_col IS NOT NULL;
CREATE INDEX tmp_indx_temp_table_name_goes_here_2 ON #temp_table_name_goes_here (the_second_col)
WHERE the_second_col IS NOT NULL;
Run Code Online (Sandbox Code Playgroud)