【发布时间】:2011-07-12 20:46:01
【问题描述】:
在 Oracle 10gR2 上,给定以下查询,它需要永远运行。这是因为 select 子句中的所有相关子查询。必须有更好的方法。我认为将相关子查询重写为连接可以解决问题,或者以只需要一个相关子查询的方式构建查询,或者可能使用某种类型的分析函数,但到目前为止它超出了我的范围。任何帮助将不胜感激。
这是查询:
SELECT COL_1,
TAB_1.COL_2 AS REPORT,
(SELECT COL_3
FROM TAB_2
WHERE TAB_2.COL_1 = TAB_1.COL_1) AS DEPOT,
(SELECT COUNT(DISTINCT( TAB_3.COL_4 ))
FROM TAB_3
WHERE TAB_3.COL_9 = TAB_1.COL_1
AND TAB_1.COL_2 = TAB_3.COL_6
AND TAB_3.COL_5 IS NULL
AND TAB_3.COL_8 = 'Parts Shortage') AS P_SHORTAGES,
(SELECT COUNT(DISTINCT( Trim(COL_10) ))
FROM TAB_3
WHERE TAB_3.COL_9 = TAB_1.COL_1
AND TAB_1.COL_2 = TAB_3.COL_6
AND TAB_3.COL_5 IS NULL
AND TAB_3.COL_8 = 'Parts Shortage') AS PARTS_AFFECTED,
(SELECT COUNT(TAB_3.COL_7)
FROM TAB_3
WHERE TAB_3.COL_7 = 1
AND TAB_3.COL_9 = TAB_1.COL_1
AND TAB_1.COL_2 = TAB_3.COL_6
AND TAB_3.COL_5 IS NULL
AND TAB_3.COL_8 = 'Parts Shortage') AS PARTS_CATEGORY1,
(SELECT COUNT(TAB_3.COL_4)
FROM TAB_3
WHERE TAB_3.COL_9 = TAB_1.COL_1
AND TAB_3.COL_6 = TAB_1.COL_2
AND TAB_3.COL_5 IS NULL
AND TAB_3.COL_8 = 'Unsrv Asset') AS U_SHORTAGES,
(SELECT COUNT(TAB_3.COL_10)
FROM TAB_3
WHERE TAB_3.COL_9 = TAB_1.COL_1
AND TAB_3.COL_6 = TAB_1.COL_2
AND TAB_3.COL_5 IS NULL
AND TAB_3.COL_8 = 'Unsrv Asset') AS U_AFFECTED,
(SELECT COUNT(DISTINCT( Trim(TAB_3.COL_7) ))
FROM TAB_3
WHERE TAB_3.COL_7 = 1
AND TAB_3.COL_9 = TAB_1.COL_1
AND TAB_3.COL_6 = TAB_1.COL_2
AND TAB_3.COL_5 IS NULL
AND TAB_3.COL_8 = 'Unsrv Asset') AS UNSRV_CAT1,
To_char(TAB_1.COL_11, 'MM/DD/YY') AS REPORT_DATE
FROM TAB_1;
为了让事情变得不那么复杂,我尝试只重写以下内容,但我仍然不知所措:
SELECT COL_1,
(SELECT COUNT(DISTINCT( TAB_3.COL_4 ))
FROM TAB_3
WHERE TAB_3.COL_9 = TAB_1.COL_1
AND TAB_1.COL_2 = TAB_3.COL_6
AND TAB_3.COL_5 IS NULL
AND TAB_3.COL_8 = 'Parts Shortage') AS P_SHORTAGES
FROM TAB_1;
【问题讨论】:
-
在决定是否需要重写查询之前 - 您可能会 - 您是否对查询运行了解释计划?你从中得到了什么?并告诉我们您在表格上的索引。特别是,如果 TAB_3 (COL_9,COL6,COL_8) 上有索引,我会很感兴趣。并检查您是否有关于表格的最新统计数据。
-
我当然希望这些不是实际的表名和列名。如果是,您可能会考虑寻找一个理智的工作场所。
-
这很有趣。是的,这些列有更合理的名称。更改名称只是为了稍微抽象一下数据库并保护无辜者。该数据库本质上有点机密。
标签: oracle performance select correlated-subquery