考虑一下这个查询,它由N自联接组成:
select
t1.*
from [Table] as t1
join [Table] as t2 on
t1.Id = t2.Id
-- ...
join [Table] as tN on
t1.Id = tN.Id它生成一个具有N个聚集索引扫描和N-1合并联接的执行计划.
老实说,我看不出有什么理由不优化所有联接,只进行一次聚集索引扫描,即优化原始查询:
select
t1.*
from [Table] as t1在以下方面测试:
这个查询没有任何意义;它只是突然出现在我的脑海中,我现在对它很好奇。
下面是创建表和三个查询的小提琴:使用inner join's,使用left join's和混合。您也可以查看执行计划。
结果执行计划中,left joins似乎被淘汰,而inner joins则没有被淘汰。但还是不明白为什么。
发布于 2017-08-30 19:08:25
在关系术语中,任何没有属性重命名的自联接都是没有操作的,可以安全地从执行计划中删除。不幸的是,SQL不是关系型的,优化器可以消除自联接的情况仅限于少数边缘情况。
SQL的SELECT语法使联接逻辑优先于投影。SQL对列名的范围界定规则以及允许重复列名和未命名列的事实使得SQL查询优化比关系代数优化要困难得多。SQL供应商有有限的资源,必须对他们想要支持的哪种优化进行选择。
发布于 2017-08-30 17:25:31
主键始终是唯一的,并且不允许空值,因此在主键上将表连接到自己(不使用自引用辅助键且没有where语句)将产生与原始表相同的行数。
至于为什么他们不优化它,我会说这是一个边缘的情况,他们要么没有计划,或者假设人们不会这样做。在有保证的唯一主键上将表连接到表本身并不能达到目的。
https://dba.stackexchange.com/questions/184722
复制相似问题