Q1:Có vẻ như không có gì về thời gian tính toán, chỉ là lỗi trong thuật toán trình tối ưu hóa khiến nó trở nên điên rồ trong khi tính toán một kế hoạch thực thi tốt nhất.
Câu hỏi 2:Có một số lỗi đã biết và đã sửa trong Oracle 11.X.0.X liên quan đến việc tối ưu hóa các truy vấn lồng nhau và bao thanh toán truy vấn. Nhưng rất khó để tìm ra một vấn đề cụ thể.
Câu 3:Có hai không có giấy tờ gợi ý:materialize
và inline
nhưng không ai trong số họ làm việc cho tôi trong khi tôi đã thử ví dụ của bạn. Có thể một số thay đổi trong cấu hình máy chủ hoặc nâng cấp lên 11.2.0.3 có thể làm tăng giới hạn with
mệnh đề:đối với tôi (trên 11.2.0.3 Win7 / x86) ví dụ của bạn hoạt động tốt, nhưng việc tăng số lượng bảng lồng nhau lên 30 sẽ bị treo một phiên.
Cách giải quyết khác có thể giống như sau:
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
)
Ít nhất thì nó hoạt động với tôi ở cấp độ lồng nhau là 30 và tạo ra kế hoạch thực thi hoàn toàn khác với WINDOW BUFFER
và VIEW
thay vì LOAD TABLE AS SELECT
, SORT AGGREGATE
và TABLE ACCESS FULL
.
Cập nhật
-
Chỉ cần cài đặt 11.2.0.4 (Win7 / 32bit) và kiểm tra nó với truy vấn ban đầu. Không có gì thay đổi trong hành vi của trình tối ưu hóa.
-
Không có khả năng ảnh hưởng trực tiếp đến hành vi CBO, ngay cả khi sử dụng
inline
(không có giấy tờ) hoặcRULE
(không dùng nữa) gợi ý. Có thể một số Guru biết một số biến thể, nhưng đó là một Bí mật hàng đầu đối với tôi (và cả Google nữa :-). -
Có thể thực hiện mọi việc trong một câu lệnh select trong thời gian hợp lý nếu một câu lệnh select chính được tách thành các phần và được đặt vào hàm trả về một tập hợp các hàng (hàm trả về sys_refcursor hoặc con trỏ được gõ mạnh), nhưng nó không phải là lựa chọn nếu truy vấn được tạo trong thời gian chạy.
-
Có thể giải pháp thay thế bằng cách sử dụng XML,
nhưng biến thể này trông giống như loại bỏ amidan qua lỗ đít(xin lỗi):
.
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
)
)
)
)))
Một điều khác về mã kỳ lạ ở trên là biến thể này chỉ áp dụng nếu with
tập dữ liệu không có nhiều hàng.