优化 Oracle SQL 查询
Posted
技术标签:
【中文标题】优化 Oracle SQL 查询【英文标题】:Optimizing an Oracle SQL Query 【发布时间】:2011-04-21 17:15:28 【问题描述】:这是我的一个查询,它返回员工的主管链,但它使用了一堆嵌套的 SELECT 语句。 我想知道这个查询是否可以被重构以提高效率。该查询适用于 3 级管理授权员工参加培训课程的应用程序。目前我们需要 3 个级别的批准,但这可能会更改为 4 个或更多。
SELECT badge as employee,
supervisor_badge as boss1,
(select supervisor_badge FROM hr_data level2 WHERE badge = level1.supervisor_badge) as boss2
(select supervisor_badge FROM hr_data level3 WHERE badge =
(select supervisor_badge FROM hr_data level2 WHERE badge = level1.supervisor_badge)) as boss3
FROM hr_data level1 WHERE BADGE = '123456';
徽章 = 员工 ID supervisor_badge = 员工主管的徽章 这两个字段都在 hr_data 表中
badge supervisor_badge
123456 111111
111111 454545
454545 332211
输出
employee boss1 boss2 boss3
123456 111111 454545 332211
【问题讨论】:
您希望它运行得更快还是更动态?这样您的级别就可以增长而无需更改 select 语句? 我猜很容易维护。申请冠军可能会要求我获得 5 个级别的批准。 Mikes 在下面的回答可以轻松做到这一点。 【参考方案1】:我没有手边的数据库来模拟这个,所以我会动起来。为了清楚起见,我尝试使用相同的命名约定。
SELECT level1.badge as employee
,level2.badge as boss1
,level3.badge as boss2
,level3.supervisor_badge as boss3
FROM hr_data level1
INNER JOIN hr_data level2
ON level2.badge = level1.supervisor_badge
INNER JOIN hr_data level3
ON level3.badge = level2.supervisor_badge
WHERE level1.badge = '123456'
重要提示:这将只返回所有连接处都存在数据的记录。要返回少于 3 个 boss 的记录(即只有 boss1 和 boss2,但没有 boss3),请将 INNER JOIN 语句更改为 LEFT JOIN。
【讨论】:
谢谢迈克。您的查询开箱即用即可正常工作。它使添加或删除级别变得容易。【参考方案2】:使用联接而不是子查询。
SELECT
e.badge, b1.badge, b2.badge, b3.badge
FROM
hr_data e
LEFT JOIN hr_data b1 ON e.badge=b1.badge
LEFT JOIN hr_data b2 ON b1.badge=b2.badge
LEFT JOIN hr_data b3 ON b2.badge=b3.badge
WHERE
e.badge='123456';
由于级别是可变的,您可能需要考虑使用存储过程在内部循环预先指定的级别数量(直到它到达顶部,例如您的 CEO)。
【讨论】:
+1 提醒我使用 JOINS 而不是 SUBQUERIES。不过,您的查询缺少主管徽章。以上是关于优化 Oracle SQL 查询的主要内容,如果未能解决你的问题,请参考以下文章