坚持逻辑 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,以便我有两个子句分开的子句。
我一直在优化这个 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,以便我有两个子句分开的子句。