【发布时间】:2009-04-23 16:15:23
【问题描述】:
我在游标中使用的 Oracle 选择语句存在性能问题。在语句中,SELECT 子句中的一个术语的评估成本很高(它是一个 PL/SQL 过程调用,它对数据库的访问量很大)。但是,WHERE 子句和 ORDER BY 子句很简单。
我希望 Oracle 会首先执行 WHERE 子句来识别与查询匹配的记录集,然后执行 ORDER BY 子句对它们进行排序,最后评估 SELECT 子句中的每个术语.由于我在游标中使用此语句,然后从中提取结果,因此我预计只有在从游标请求每个结果时,才会根据需要执行对 SELECT 术语的昂贵评估。
但是,我发现这不是 Oracle 使用的顺序。相反,它似乎会在执行排序之前评估与 WHERE 子句匹配的每条记录的 SELECT 子句中的术语。因此,在从游标返回任何结果之前,会为结果集中的每个结果结果调用调用代价高昂的过程。
我希望能够尽快从光标中获取第一个结果。谁能告诉我如何说服 Oracle 在执行排序之前不要评估 SELECT 语句中的过程调用?
这在示例代码中可能更容易描述:
给定一个表example 与列a、b、c 和d,我有这样的声明:
select a, b, expensive_procedure(c)
from example
where <the_where_clause>
order by d;
在执行此操作时,会为每条匹配 WHERE 子句的记录调用 expensive_procedure(),即使我将语句作为游标打开并且只从中提取一个结果。
我尝试将语句重组为:
select a, b, expensive_procedure(c)
from example, (select example2.rowid, ROWNUM
from example example2
where <the_where_clause>
order by d)
where example.rowid = example2.rowid;
ROWNUM 在内部 SELECT 语句中的存在迫使 Oracle 首先评估它。这种重组具有预期的性能优势。不幸的是,它并不总是尊重所需的顺序。
为了清楚起见,我知道我不会改进返回整个结果集所需的时间。我希望缩短从语句返回前几个结果所需的时间。我希望在迭代游标的结果时所花费的时间是渐进的,而不是在返回第一个结果之前所有的时间都过去。
任何 Oracle 专家可以告诉我如何说服 Oracle 在必要之前停止执行 PL/SQL?
【问题讨论】:
-
您尝试过 FIRST_ROWS(1) 提示吗?
标签: sql performance oracle