数据库关系代数优化

时间:2010-11-27 19:20:14

标签: sql relational-database relational-algebra

我正在尝试进行一些查询优化;将SQL查询带入关系代数并进行优化。

我的数据库表模式如下:

Hills(MId, Mname, Long, Lat, Height, Rating,... )
Runners(HId, HName, Age, Skill,... )
Runs(MId, CId, Date, Duration)

Runners and Hills中可能有很多列。

我的SQL查询是:

SELECT DISTINCT Runners.HName, Runners.Age
FROM Hills, Runners, Runs
WHERE Runners.HId = Runs.HId AND Runs.MID = Hills.MId AND Height > 1200

所以我可以先做:

π Name, Age(σ Height > 1200 (Hills × Runners × Runs))

或类似的东西,然后用一个很好的连接选择来优化它,但我不知道从哪里开始

1 个答案:

答案 0 :(得分:3)

您可以从使用SQL连接表示法开始:

SELECT DISTINCT P.HName, P.Age
  FROM Hills   AS H
  JOIN Runs    AS R ON H.MId = R.MId
  JOIN Runners AS P ON P.HId = R.HId
 WHERE H.Height > 1200

然后您可以观察到WHERE条件仅适用于Hills,因此您可以按下搜索条件:

SELECT DISTINCT P.HName, P.Age
  FROM (SELECT MId FROM Hills WHERE Height > 1200) AS H
  JOIN Runs    AS R ON H.MId = R.MId
  JOIN Runners AS P ON P.HId = R.HId

这是标准优化 - SQL优化器将自动执行此操作。实际上,可能不值得对显示的第一个查询进行大量重写,因为优化器可以处理它。我认为可能的另一个优化是将DISTINCT操作推向一个级别:

SELECT P.HName, P.Age
  FROM (SELECT DISTINCT R.HId
          FROM (SELECT MId FROM Hills WHERE Height > 1200) AS H
          JOIN Runs AS R ON H.MId = R.MId
       ) AS R1
  JOIN Runners AS P ON P.HId = R1.HId

这使得中间结果集尽可能地小:R1包含运行至少一个1200米(或1200英尺?)小山的人的ID值列表,并且可以1:1连接使用Runners表中的详细信息。看看优化器是否能够推断出DISTINCT的下推是很有趣的。

当然,在关系代数中,DISTINCT操作是“自动”完成的 - 每个结果和中间结果总是一个没有重复的关系。


鉴于原始的“关系代数”符号:

  • π姓名,年龄(σ高度> 1200(Hills×Runners×Runs))

这对应于上面的第一个SQL语句。

然后,第二个SQL语句(或多或少)对应于:

  • π名称,年龄((πMId(σHeight> 1200(Hills)))×跑步者×跑步

然后,第三个SQL语句(或多或少)对应于:

  • π名称,年龄((πHdd((πMId(σHeight> 1200(Hills)))×Runs))×跑步者)

我假设括号强制关系代数按顺序计算表达式。我不确定那里是否有尽可能少的括号,但那里的括号并没有留下太大的暧昧空间。