Q1:Sepertinya tidak ada apa-apa tentang waktu perhitungan, hanya bug dalam algoritma pengoptimal yang membuatnya gila saat menghitung rencana eksekusi terbaik.
Q2:Ada sejumlah bug yang diketahui dan diperbaiki di Oracle 11.X.0.X terkait dengan optimalisasi kueri bersarang dan pemfaktoran kueri. Tapi sangat sulit untuk menemukan masalah yang konkrit.
T3:Ada dua tidak berdokumen petunjuk:materialize
dan inline
tetapi tidak ada yang bekerja untuk saya ketika saya mencoba contoh Anda. Ada kemungkinan bahwa beberapa perubahan dalam konfigurasi server atau peningkatan ke 11.2.0.3 dapat meningkatkan batas with
bersarang klausa:bagi saya (pada 11.2.0.3 Win7/x86) contoh Anda berfungsi dengan baik, tetapi peningkatan jumlah tabel bersarang menjadi 30 hang per sesi.
Solusinya mungkin terlihat seperti ini:
select k from (
select k, avg(k) over (partition by null) k_avg from ( --t16
select k, avg(k) over (partition by null) k_avg from ( --t15
select k, avg(k) over (partition by null) k_avg from ( --t14
select k, avg(k) over (partition by null) k_avg from ( --t13
select k, avg(k) over (partition by null) k_avg from ( --t12
select k, avg(k) over (partition by null) k_avg from ( --t11
select k, avg(k) over (partition by null) k_avg from ( --t10
select k, avg(k) over (partition by null) k_avg from ( --t9
select k, avg(k) over (partition by null) k_avg from ( --t8
select k, avg(k) over (partition by null) k_avg from ( --t7
select k, avg(k) over (partition by null) k_avg from ( --t6
select k, avg(k) over (partition by null) k_avg from ( --t5
select k, avg(k) over (partition by null) k_avg from ( --t4
select k, avg(k) over (partition by null) k_avg from ( --t3
select k, avg(k) over (partition by null) k_avg from ( --t2
select k, avg(k) over (partition by null) k_avg from ( -- t1
select k, avg(k) over (partition by null) k_avg from (select 0 as k from dual) t0
) where k >= k_avg
) where k >= k_avg
) where k >= k_avg
) where k >= k_avg
) where k >= k_avg
) where k >= k_avg
) where k >= k_avg
) where k >= k_avg
) where k >= k_avg
) where k >= k_avg
) where k >= k_avg
) where k >= k_avg
) where k >= k_avg
) where k >= k_avg
) where k >= k_avg
) where k >= k_avg
)
Setidaknya itu bekerja untuk saya pada level bersarang 30 dan menghasilkan rencana eksekusi yang sama sekali berbeda dengan WINDOW BUFFER
dan VIEW
alih-alih LOAD TABLE AS SELECT
, SORT AGGREGATE
dan TABLE ACCESS FULL
.
Perbarui
-
Baru saja menginstal 11.2.0.4 (Win7/32bit) dan mengujinya terhadap kueri awal. Tidak ada yang berubah dalam perilaku pengoptimal.
-
Tidak ada kemungkinan untuk secara langsung memengaruhi perilaku CBO, bahkan dengan penggunaan
inline
(tidak berdokumen) atauRULE
(usang) petunjuk. Mungkin beberapa Guru mengetahui beberapa varian, tapi itu Rahasia Utama bagi saya (dan Google juga :-) . -
Melakukan sesuatu dalam satu pernyataan pemilihan dalam waktu yang wajar dimungkinkan jika pernyataan pemilihan utama dipisahkan menjadi beberapa bagian dan ditempatkan ke dalam fungsi yang mengembalikan satu set baris (fungsi mengembalikan sys_refcursor atau kursor yang diketik kuat), tetapi itu bukan pilihan jika permintaan dibangun saat runtime.
-
Pemecahan masalah dengan penggunaan XML dimungkinkan,
tetapi varian ini terlihat seperti mengeluarkan amandel melalui lubang pantat(maaf):
.
select
extractvalue(column_value,'/t/somevalue') abc
from
table(xmlsequence((
select t2 from (
select
t0,
t1,
(
select xmlagg(
xmlelement("t",
xmlelement("k1",extractvalue(t1t.column_value,'/t/k1')),
xmlelement("somevalue", systimestamp))
)
from
table(xmlsequence(t0)) t0t,
table(xmlsequence(t1)) t1t
where
extractvalue(t1t.column_value,'/t/k1') >= (
select avg(extractvalue(t1t.column_value, '/t/k1')) from table(xmlsequence(t1))
)
and
extractvalue(t0t.column_value,'/t/k2') > 6
) t2
from (
select
t0,
(
select xmlagg(
xmlelement("t",
xmlelement("k1",extractvalue(column_value,'/t/k1')),
xmlelement("somevalue", sysdate))
)
from table(xmlsequence(t0))
where
extractvalue(column_value,'/t/k1') >= (
select avg(extractvalue(column_value, '/t/k1')) from table(xmlsequence(t0))
)
) t1
from (
select
xmlagg(xmlelement("t", xmlelement("k1", level), xmlelement("k2", level + 3))) t0
from dual connect by level < 5
)
)
)
)))
Hal lain tentang kode aneh di atas adalah varian ini hanya berlaku jika with
kumpulan data tidak memiliki banyak baris.