このクエリは、16 の等しいステップで構成されています。
すべてのステップは同じデータセット (単一の行) に対して同じ計算を行ってい
ますが、最後のステップでは時間がかかりすぎます。
with t0 as (select 0 as k from dual)
,t1 as (select k from t0 where k >= (select avg(k) from t0))
,t2 as (select k from t1 where k >= (select avg(k) from t1))
,t3 as (select k from t2 where k >= (select avg(k) from t2))
,t4 as (select k from t3 where k >= (select avg(k) from t3))
,t5 as (select k from t4 where k >= (select avg(k) from t4))
,t6 as (select k from t5 where k >= (select avg(k) from t5))
,t7 as (select k from t6 where k >= (select avg(k) from t6))
,t8 as (select k from t7 where k >= (select avg(k) from t7))
,t9 as (select k from t8 where k >= (select avg(k) from t8))
,t10 as (select k from t9 where k >= (select avg(k) from t9))
,t11 as (select k from t10 where k >= (select avg(k) from t10))
,t12 as (select k from t11 where k >= (select avg(k) from t11)) -- 0.5 sec
,t13 as (select k from t12 where k >= (select avg(k) from t12)) -- 1.3 sec
,t14 as (select k from t13 where k >= (select avg(k) from t13)) -- 4.5 sec
,t15 as (select k from t14 where k >= (select avg(k) from t14)) -- 30 sec
,t16 as (select k from t15 where k >= (select avg(k) from t15)) -- 4 min
select k from t16
サブクエリ t10 はすぐに完了しますが、クエリ全体 (t16) が完了するまでに 4 分かかります。
Q1. 同じデータに対する同一のサブクエリの計算時間が大きく異なるのは
なぜですか?
Q2.
Oracle 9 では非常に高速に実行され、Oracle 11
では非常に低速に実行されるため、バグのように見えます。実際、長くて複雑な with-clause を含むすべての select ステートメントは同じように動作します。
それは既知のバグですか?(メタリンクにアクセスできません)
どのような回避策が推奨されますか?
Q3.
Oracle 11 用のコードを作成する必要があり、単一の選択ステートメントですべての計算を行う必要があります。
長いステートメントを 2 つの別々のステートメントに分割して高速化することはできません。クエリ全体 (t16) を妥当な時間 (たとえば、1 秒以内) で完了するためのヒント (または何らかのトリック) が Oracle
に存在しますか? 私はそのようなものを見つけようとしましたが、役に立ちませんでした。
ところで、実行計画は優れており、コストはステップ数の線形関数 (指数関数的ではない) として動作します。