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

Cho phép Oracle biến đổi các vị từ được kết nối OR thành UNION ALL hoạt động

Tôi tin rằng điều này có thể liên quan đến các chỉ mục hiện có trên các cột bạn sử dụng trong OR vị ngữ.

Tôi đã thử nghiệm bằng cách sử dụng phần sau trong 11gR2.

create table scott.test as 
select level l, 
       decode(mod(level,2), 1, 1, 2) x, 
       decode(mod(level,2), 1, 2, 1) y, 
       dbms_random.value(1, 3) z from dual 
connect by level < 1000;
/

begin
   dbms_stats.gather_table_stats('scott', 'test');
end;
/

Sau đó, tôi giải thích các truy vấn sau trong TOAD, (EXPLAIN PLAN FOR )

select x, y, z from scott.test
    where (floor(z) = 1 and x = 1) or (floor(z) = 2 and y = 1)
    ;

SELECT STATEMENT Optimizer Mode=ALL_ROWS        10          4                                
  TABLE ACCESS FULL COS_DM.TEST 10      280     4   

select /*+ USE_CONCAT */ x, y, z from scott.test
where (floor(z) = 1 and x = 1) or (floor(z) = 2 and y = 1)
;

SELECT STATEMENT Optimizer Mode=ALL_ROWS        10          4                                
  TABLE ACCESS FULL COS_DM.TEST 10      280     4                                


select x, y, z from test where (floor(z) = 1 and x = 1)
union all
select x, y, z from test where (floor(z) = 2 and y = 1)
;

SELECT STATEMENT Optimizer Mode=ALL_ROWS        10          8                                
  UNION-ALL                                              
    TABLE ACCESS FULL   COS_DM.TEST 5   140     4                                
    TABLE ACCESS FULL   COS_DM.TEST 5   140     4                                

Vì vậy, nó xuất hiện gợi ý không hoạt động. Sau đó, tôi đã thêm một chỉ mục vào các cột x &y:

create index test_x on test (x, y);

begin
   dbms_stats.gather_table_stats('scott', 'test');
end;
/

Chạy lại các truy vấn ngay bây giờ:

select x, y, z from scott.test
    where (floor(z) = 1 and x = 1) or (floor(z) = 2 and y = 1)
    ;

SELECT STATEMENT Optimizer Mode=ALL_ROWS        10          4                                
  TABLE ACCESS FULL COS_DM.TEST 10      280     4   

select /*+ USE_CONCAT */ x, y, z from scott.test
where (floor(z) = 1 and x = 1) or (floor(z) = 2 and y = 1)
;

SELECT STATEMENT Optimizer Mode=ALL_ROWS        10          8                                
  CONCATENATION                                              
    TABLE ACCESS FULL   COS_DM.TEST 5   140     4                                
    TABLE ACCESS FULL   COS_DM.TEST 5   140     4                                

select x, y, z from test where (floor(z) = 1 and x = 1)
union all
select x, y, z from test where (floor(z) = 2 and y = 1)
;

SELECT STATEMENT Optimizer Mode=ALL_ROWS        10          8                                
  UNION-ALL                                              
    TABLE ACCESS FULL   COS_DM.TEST 5   140     4                                
    TABLE ACCESS FULL   COS_DM.TEST 5   140     4                                

Có vẻ như sau khi thêm chỉ mục (mặc dù nó không được sử dụng ) sau cùng, trình tối ưu hóa đã quyết định sử dụng gợi ý!

Có lẽ bạn có thể thử điều này?



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Kết nối bên trong SQL trên các câu lệnh chọn

  2. Oracle SQL:Nhận được lỗi 'không khớp với khóa duy nhất hoặc khóa chính' và không biết tại sao

  3. cung cấp tên người dùng và mật khẩu chính xác, nhận được ORA-01017:tên người dùng / mật khẩu không hợp lệ; Đăng nhập đã bị từ chối

  4. Cách tạo hàm PL / SQL trong cơ sở dữ liệu Oracle

  5. trình tự ngày oracle?