我在学校的教科书中看到,许多连接操作似乎从来没有优化连接右边的表格,只在左边。
例如,要查找管理数据库部门的员工的名称,您可以这样做:
name ( Mgr_ssn ( Dname ='Database') (部门))⨝ Mgr_ssn = ssn 员工)
所以我想知道做同样的事情是否同样正确:
name ( Mgr_ssn ( Dname ='Database'(Department))⨝ Mgr_ssn = ssn ( ssn ,名称员工))
这当然假设员工有许多其他属性。在这样做时,我认为系统可以节省时间,而不必担心加入Employee的所有其他属性,最终他们将被投射出去。我从来没有在连接的右侧看过这样的投影,我想知道它是否可以接受和/或是不必要的。
答案 0 :(得分:1)
大多数优化器使用系统R优化器,它只考虑左深连接。这就是为什么你从来没有看到右边的连接。
所有选项的搜索空间都是指数级的,因此优化器希望快速找到合理可接受的解决方案(优化器找不到最佳解决方案,他们会尽量避免最坏的解决方案)。
P.S。使用左深连接的原因是它允许对结果进行流水线操作而无需将其写入磁盘,从而节省了I / O.
答案 1 :(得分:1)
任何体面的查询优化器都会降低适当的限制,有时还会进行预测,以最大限度地减少要处理的数据。并且因为优化器会自动执行,结果相同,所以不需要在关系代数中优化表达式。
在这样的两表连接序列中,不清楚在与部门合作之前形成投影会有好处;可能的处理顺序是找到具有Dname ='Database'的(可能是单个)部门,然后在Employee中找到具有E.SSN = D.Mgr_SSN的单行。但是,如果多次使用子表达式,则可能值得这样做。
我还注意到设计很糟糕 - 你不应该像SSN那样使用像数据库设计中的连接字段那样敏感的东西。 PCI团队很合适!但也许这些名字是现在很久以来的温和时代的宿醉,但内容是生成的代理,真正的SSN存储在Employee.RealSSN中(甚至可以加密以确保未经授权的人看不到它 - 尽管设置了在列上正确的权限,以便只有授权可以选择它也是有效的。)