Oracle
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Oracle

Hiệu suất chậm đối với bao thanh toán truy vấn con lồng nhau (CTE)

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 ý:materializeinline 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 BUFFERVIEW thay vì LOAD TABLE AS SELECT , SORT AGGREGATETABLE ACCESS FULL .

Cập nhật

  1. 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.

  2. 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ặc RULE (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 :-).

  3. 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.

  4. 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.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Làm cách nào để thêm ojdbc7 vào ứng dụng web Java bằng Gradle?

  2. ORA-01264 ở chế độ chờ vật lý

  3. SQL động ASC và DESC

  4. Truy vấn Oracle TIMESTAMP VỚI TIMEZONE

  5. Chuyển đổi oracle to_date hiển thị chữ không khớp với định dạng chuỗi