【发布时间】:2015-06-05 09:06:38
【问题描述】:
我坚持在关系代数中优化这个 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
但是我如何优化其余的 where 呢? 我想过用分配规则把它变成KNF,
(R1.A='1' ∨ R2.B='2') ∧ (R1.A='1' ∨ R3.C=R4.C)
这将允许我独立处理这两个子句。但我不知道如何继续,尤其是我应该以什么顺序加入或制作笛卡尔积。
这是运算符树,我画了:
【问题讨论】:
-
“优化”到底是什么意思?这和 SQLite 有什么关系?
-
@CL 优化意味着,使用关系代数的逻辑规则来降低评估成本并优化查询运算符的顺序,例如尽可能向下移动选择等。用 sqlite 标记,因为 SQL 语法适用于 sqlite(我使用 sqlite 作为数据库系统)示例:cs.uni-paderborn.de/fileadmin/Informatik/AG-Boettcher/Lehre/…
-
我可能不对,但在您的翻译中,您省略了一对括号。在原始查询中,您有:
(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' -
在现实世界中,我会将
R4.D检查分配到OR的操作数中,以便SQLite 能够应用OR optimization,如果它愿意的话。这主要取决于索引的存在,但这种物理考虑不是您当前任务的一部分。无论如何,在R3/R4加入之前进行R4.D检查应该会提高选择性。 -
@T_G 是的,你是对的。
标签: sql sqlite relational-algebra