0

我有以下脚本。为了减少执行时间,我将 get_function() 替换为常量 'ABCD' (这是 get_function() 的结果)。我希望减少执行时间;而有趣的是,执行时间增加了近 4 倍。

alter system flush buffer_cache; 
alter system flush shared_pool; 
Set timing on; 
declare x number(3); 
begin 
    select v.QTY 
    into x 
    from viewName v 
    where v.col1 = get_function() --'ABCD'; 
    exception when others then dbms_output.put_line(sqlerrm||' '||sqlcode); 
end; 
Set timing off;
4

2 回答 2

3

原因是两个查询之间的执行计划发生了变化(前者显然更高效)。

每个查询的执行计划都是独立计算的,两个语法不同的查询没有理由产生完全相同的计划。Oracle 使用规则、统计和概括在合理的时间内生成计划。CBO(基于成本的优化器)采取的每一步都是可能导致次优计划的近似值。通常,有了最新的统计数据,对于简单的查询,Oracle 会产生一个合理的计划。有时,您必须通过提示、精心挑选的统计数据、调整参数或其他优化工具来帮助 Oracle 选择最佳计划。

既然你没有给出其他说明,我们只能推测第二个计划更糟糕的原因。我的第一个猜测是,第二个查询产生一个INDEX RANGE SCAN不适合的,而第一个查询产生一个有效的FULL TABLE SCAN.

于 2012-09-13T12:36:34.030 回答
1

到目前为止,在 column1 上没有过滤器,它可能正在使用一些索引。一旦您引入了不属于任何这些索引的 column1,将执行表扫描(因为这是一个 varchar 列),因此会增加执行时间。您应该在 column1 上添加此新过滤器之前和之后查看视图的执行计划,您将能够找出正确的索引定义/修改。

于 2012-09-13T12:37:36.253 回答