坚持逻辑 SQL 关系代数中的查询优化(或在 WHERE 中)

Stuck with Logical SQL Query optimizations in Relational Algebra (OR in WHERE)

我一直在优化这个 SQL-关系代数中的查询:

SELECT * FROM R1, R2, R3, R4 
WHERE (R1.A = '1' OR (R2.B = '2' AND R3.C = R4.C)) AND R4.D = '4'

我将其翻译成以下关系代数语句:

σ{R1.A='1'  ∨ (R2.B='2'  ∧  R3.C=R4.C) ∧ R4.D='4'}(R1 × R2 × R3 × R4)

我的问题是,我真的不知道如何优化 where 语句。 我知道我可以将最后一个条件转换为 σ{R4.D='4'}(R4) 并将其直接向下移动到树中的 R4。 存在某种优化规则,但我真的不知道如何处理 OR。 Rules for Logical Query Optimization

但是我该如何优化剩下的地方呢? 我想过用分配规则把它转化成KNF,

(R1.A='1' ∨ R2.B='2')  ∧ (R1.A='1'  ∨  R3.C=R4.C) 

这将使我能够独立处理这两个子句。但是我不知道如何继续,尤其是我应该按什么顺序加入或制作笛卡尔积。

这是运算符树,我画的:

在查询优化中处理析取的一个好方法是将选择条件转换为析取范式(DNF),然后将选择重写为选择并集(每个析取一个)。

即在此处应用规则 #2:https://en.wikipedia.org/wiki/Relational_algebra#Breaking_up_selections_with_complex_conditions

作为查询优化中的大多数技巧,它在某些情况下效果很好,但在其他情况下效果不佳 - 这就是为什么 SQL 优化器搜索 space 计划,试图提出一个像样的计划。

无法合并,因为它需要相同类型的列。 我现在从我的导师那里得到了一个官方解决方案。 正如我已经想到的,需要使用分配规则将其转换为KNF,以便我有两个子句分开的子句。