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

その理由は、実行計画が 2 つのクエリ間で変更されたためです (前者の方が明らかに効率的です)。

実行計画はクエリごとに個別に計算され、2 つの構文的に異なるクエリがまったく同じ計画を生成する理由はありません。オラクルは、規則、統計および一般化を使用して、合理的な時間内に計画を作成します。CBO (Cost-Based-Optimizer) が実行する各ステップは概算であり、最適ではない計画につながる可能性があります。通常、最新の統計を使用して、単純なクエリの場合、オラクルは合理的な計画を作成します。場合によっては、オラクルがヒント、厳選された統計、調整されたパラメーター、またはその他の最適化ツールを使用して最適な計画を選択できるようにする必要があります。

あなたは他に何の示唆も与えていないので、2 番目の計画がより悪い理由については推測することしかできません。私の最初の推測はINDEX RANGE SCAN、最初のクエリが効率的な を生成するのに対し、2 番目のクエリはあまり適していない を生成するということFULL TABLE SCANです。

于 2012-09-13T12:36:34.030 に答える
1

これまでのところ、column1 のフィルターがなければ、いくつかのインデックスを使用している可能性があります。これらのインデックスの一部ではない column1 を導入すると、(これは varchar 列であるため) テーブル スキャンが実行されるため、実行時間が長くなります。この新しいフィルターを column1 に追加する前と後に、ビューの実行計画を確認する必要があります。これにより、正しいインデックスの定義/変更を把握できます。

于 2012-09-13T12:37:36.253 に答える