首先,让我们假设它(id)
是表的主键。在这种情况下,是的,联接是(可以证明)冗余的,可以消除。
现在仅仅是理论-或数学。为了使优化程序进行实际消除,必须将理论转换为代码并添加到优化程序的优化/重写/消除套件中。为此,(DBMS)开发人员必须认为这将对效率产生很好的好处,并且这是足够普遍的情况。
就个人而言,听起来不像一个(很常见)。就像您承认的那样,该查询看起来很傻,并且除非经过改进并且删除了多余的联接,否则审阅者不应让它通过审阅。
也就是说,确实存在消除的类似查询。Rob Farley有一个很好的相关博客文章:SQL Server中的JOIN简化。
在我们的案例中,我们要做的所有工作就是将联接更改为LEFT
联接。参见dbfiddle.uk。在这种情况下,优化器知道可以安全地删除连接而不会更改结果。(简化逻辑是很通用的,对于自联接不是特殊情况。)
当然,在原始查询中,删除INNER
联接也可能不会更改结果。但是在主键上进行自我联接并不常见,因此优化器没有实现这种情况。但是,在联接列是其中一个表的主键的情况下进行联接(或左联接)是很常见的(并且通常存在外键约束)。这导致消除连接的第二种选择:添加(自我引用!)外键约束:
ALTER TABLE "Table"
ADD FOREIGN KEY (id) REFERENCES "Table" (id) ;
瞧,连接被淘汰了!(在同一提琴中测试):这里
create table docs
(id int identity primary key,
doc varchar(64)
) ;
GO
✓
insert
into docs (doc)
values ('Enter one batch per field, don''t use ''GO''')
, ('Fields grow as you type')
, ('Use the [+] buttons to add more')
, ('See examples below for advanced usage')
;
GO
受影响的4行
--------------------------------------------------------------------------------
-- Or use XML to see the visual representation, thanks to Justin Pealing and
-- his library: https://github.com/JustinPealing/html-query-plan
--------------------------------------------------------------------------------
set statistics xml on;
select d1.* from docs d1
join docs d2 on d2.id=d1.id
join docs d3 on d3.id=d1.id
join docs d4 on d4.id=d1.id;
set statistics xml off;
GO
id | doc
-:| :----------------------------------------
1 | 每个字段输入一批,请勿使用“ GO”
2 | 输入时字段会增加
3 | 使用[+]按钮添加更多
4 | 有关高级用法,请参见下面的示例
--------------------------------------------------------------------------------
-- Or use XML to see the visual representation, thanks to Justin Pealing and
-- his library: https://github.com/JustinPealing/html-query-plan
--------------------------------------------------------------------------------
set statistics xml on;
select d1.* from docs d1
left join docs d2 on d2.id=d1.id
left join docs d3 on d3.id=d1.id
left join docs d4 on d4.id=d1.id;
set statistics xml off;
GO
id | doc
-:| :----------------------------------------
1 | 每个字段输入一批,请勿使用“ GO”
2 | 输入时字段会增加
3 | 使用[+]按钮添加更多
4 | 有关高级用法,请参见下面的示例
alter table docs
add foreign key (id) references docs (id) ;
GO
✓
--------------------------------------------------------------------------------
-- Or use XML to see the visual representation, thanks to Justin Pealing and
-- his library: https://github.com/JustinPealing/html-query-plan
--------------------------------------------------------------------------------
set statistics xml on;
select d1.* from docs d1
join docs d2 on d2.id=d1.id
join docs d3 on d3.id=d1.id
join docs d4 on d4.id=d1.id;
set statistics xml off;
GO
id | doc
-:| :----------------------------------------
1 | 每个字段输入一批,请勿使用“ GO”
2 | 输入时字段会增加
3 | 使用[+]按钮添加更多
4 | 有关高级用法,请参见下面的示例