F1:Det verkar som att det inte finns något om beräkningstid, bara fel i optimeringsalgoritmen som gör det galet när man beräknar en plan för bästa utförande.
F2:Det finns ett antal kända och fixade buggar i Oracle 11.X.0.X relaterade till optimering av kapslade frågor och query factoring. Men det är väldigt svårt att hitta en konkret fråga.
F3:Det finns två odokumenterade tips:materialize
och inline
men ingen av dem fungerar för mig medan jag provade ditt exempel. Det är möjligt att vissa ändringar i serverkonfigurationen eller uppgradering till 11.2.0.3 kan öka gränsen för kapslade with
klausuler:för mig (på 11.2.0.3 Win7/x86) fungerar ditt exempel bra, men ökat antal kapslade tabeller till 30 hänger en session.
Lösningen kan se ut så här:
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
)
Åtminstone fungerar det för mig på kapslingsnivå på 30 och ger en helt annan exekveringsplan med WINDOW BUFFER
och VIEW
istället för LOAD TABLE AS SELECT
, SORT AGGREGATE
och TABLE ACCESS FULL
.
Uppdatera
-
Installerade precis 11.2.0.4 (Win7/32bit) och testade den mot den första frågan. Ingenting har förändrats i optimerarens beteende.
-
Det finns ingen möjlighet att direkt påverka ett CBO-beteende, även med användning av
inline
(odokumenterad) ellerRULE
(föråldrade) tips. Det kanske är någon guru som känner till en variant, men det är en topphemlighet för mig (och Google också :-) . -
Att göra saker i en one select-sats inom rimlig tid är möjligt om en huvudselect-sats separeras i delar och placeras i funktionen som returnerar en uppsättning rader (funktion som returnerar sys_refcursor eller starkt skriven markör), men det är inte ett val om en fråga konstruerad vid körning.
-
Lösning med användning av XML är möjlig,
men den här varianten ser ut som att ta bort en tonsill genom rövhålet(förlåt):
.
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
)
)
)
)))
En annan sak med en konstig kod ovan är att denna variant endast gäller om with
datauppsättningar hade inte ett stort antal rader.