首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >主键上的自连接

问主键上的自连接
EN

Database Administration用户
提问于 2017-08-30 15:54:27
回答 2查看 2.1K关注 0票数 11

考虑一下这个查询,它由N自联接组成:

代码语言:javascript
复制
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合并联接的执行计划.

老实说,我看不出有什么理由不优化所有联接,只进行一次聚集索引扫描,即优化原始查询:

代码语言:javascript
复制
select
    t1.*
from [Table] as t1

问题

  • 为什么联接没有优化呢?
  • 说每个联接都不改变结果集在数学上是不正确的吗?

在以下方面测试:

  • 源服务器版本: Server 2014 (12.0.4213)
  • 源数据库引擎版:标准版
  • 源数据库引擎类型:独立的Server
  • 兼容性级别: Server 2008 (100)

这个查询没有任何意义;它只是突然出现在我的脑海中,我现在对它很好奇。

下面是创建表和三个查询的小提琴:使用inner join's,使用left join's和混合。您也可以查看执行计划。

结果执行计划中,left joins似乎被淘汰,而inner joins则没有被淘汰。但还是不明白为什么。

EN

回答 2

Database Administration用户

发布于 2017-08-30 19:08:25

在关系术语中,任何没有属性重命名的自联接都是没有操作的,可以安全地从执行计划中删除。不幸的是,SQL不是关系型的,优化器可以消除自联接的情况仅限于少数边缘情况。

SQL的SELECT语法使联接逻辑优先于投影。SQL对列名的范围界定规则以及允许重复列名和未命名列的事实使得SQL查询优化比关系代数优化要困难得多。SQL供应商有有限的资源,必须对他们想要支持的哪种优化进行选择。

票数 2
EN

Database Administration用户

发布于 2017-08-30 17:25:31

主键始终是唯一的,并且不允许空值,因此在主键上将表连接到自己(不使用自引用辅助键且没有where语句)将产生与原始表相同的行数。

至于为什么他们不优化它,我会说这是一个边缘的情况,他们要么没有计划,或者假设人们不会这样做。在有保证的唯一主键上将表连接到表本身并不能达到目的。

票数 1
EN
页面原文内容由Database Administration提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://dba.stackexchange.com/questions/184722

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档