1

我在我的学校教科书中看到,许多连接操作似乎从未优化连接右侧的表,而只优化了左侧的表。例如,要查找管理数据库部门的员工的姓名,您可以这样做:
name ( Mgr_ssn ( Dname = 'Database' ( Department ) ) ⨝<sub>Mgr_ssn = ssn Employee )

所以我想知道它是否会做类似的事情同样正确:
name ( Mgr_ssn ( Dname = 'Database' ( Department ) ) ⨝<sub>Mgr_ssn = ssn ( ssn, name Employee ) )

这当然是假设 Employee 具有许多其他属性。这样做时,我认为该系统将节省时间,因为不必担心加入 Employee 的所有其他属性,而最终它们无论如何都会被投射出来。我以前从未在连接的右侧看到过这样的投影,我想知道它是否可以接受和/或不必要。

4

2 回答 2

1

大多数优化器使用系统 R 优化器,它只考虑左深度连接。这就是为什么你永远看不到右边的连接。

所有选项的搜索空间都是指数级的,因此优化器希望快速找到合理可接受的解决方案(优化器不会找到最佳解决方案,他们会尽量避免最坏的解决方案)。

PS 使用左深连接的原因是它允许将结果流水线化,而无需将它们写入磁盘,从而节省了 I/O。

于 2011-02-10T04:16:08.927 回答
1

任何体面的查询优化器都会降低适当的限制,有时也会降低预测,以最小化要处理的数据。而且因为优化器会自动完成,结果是相同的,所以没有特别需要优化关系代数中的表达式。

在像这样的两表连接序列中,在与部门连接之前形成投影是否有好处尚不清楚;可能的处理顺序是找到 Dname = 'Database' 的(可能是单个)部门,然后在 Employee 中找到 E.SSN = D.Mgr_SSN 的单行。然而,如果子表达式被多次使用,它可能是值得的。

我还注意到这个设计很糟糕——你永远不应该在数据库设计中使用像 SSN 这样敏感的东西作为连接字段。PCI 团队会很适合的!但也许这些名字是从现在很久以前的温和时代遗留下来的,但内容是生成的代理,真正的 SSN 存储在 Employee.RealSSN 中(甚至可能被加密以确保未经授权的人看不到它 - 尽管设置列上正确的权限,以便只有授权才能选择它也是有效的)。

于 2011-02-10T06:15:12.643 回答