2011-09-07 30 views
12
SELECT COUNT (*) 
    FROM rps2_workflow 
WHERE  workflow_added > TO_DATE ('01.09.2011', 'dd.mm.yyyy') 
     AND workflow_finished < TO_DATE ('wtf', 'dd.mm.yyyy') 
     AND workflow_status IN (7, 12, 17) 
     AND workflow_worker = 159 

Tôi hy vọng truy vấn này thất bại, bởi vì kể từ ngày hợp lệ, nhưng nó sẽ trả về 0thành công truy vấn bất ngờ

Kế hoạch cho truy vấn này cho thấy rằng trên bước 8 mệnh đề không hợp lệ xử lý:

8 TABLE ACCESS BY INDEX ROWID TABLE RPS2.RPS2_WORKFLOW Object Instance: 1 Filter Predicates: ("WORKFLOW_STATUS"=7 OR "WORKFLOW_STATUS"=12 OR "WORKFLOW_STATUS"=17) AND SYS_EXTRACT_UTC("WORKFLOW_FINISHED")<SYS_EXTRACT_UTC(TO_DATE('wtf','dd.mm.yyyy')) Cost: 11 Bytes: 33 Cardinality: 1 CPU Cost: 8 M IO Cost: 10 Time: 1      

Nếu chúng ta nhận xét ra AND workflow_status IN (7, 12, 17) điều kiện - sau đó dự kiến ​​chúng tôi nhận ORA-01858: a non-numeric character was found where a numeric was expected

Nếu chúng ta nhận xét ra 012.318.sau đó chúng tôi nhận được số lượng hồ sơ phù hợp với điều kiện đó (> 0)

Làm cách nào có thể?

UPD:

Các gợi ý /*+no_index(rps2_workflow) */ không thay đổi bất cứ điều gì (trong khi trong kế hoạch chúng ta thấy rằng fullscan được thực hiện)

SELECT STATEMENT ALL_ROWSCost: 254 Bytes: 31 Cardinality: 1 CPU Cost: 34 M IO Cost: 248 Time: 4  
2 SORT AGGREGATE Bytes: 31 Cardinality: 1  
    1 TABLE ACCESS FULL TABLE RPS2.RPS2_WORKFLOW Object Instance: 1 Filter Predicates: "WORKFLOW_WORKER"=159 AND ("WORKFLOW_STATUS"=7 OR "WORKFLOW_STATUS"=12 OR "WORKFLOW_STATUS"=17) AND SYS_EXTRACT_UTC("WORKFLOW_ADDED")>SYS_EXTRACT_UTC(TIMESTAMP' 2011-09-01 00:00:00') AND SYS_EXTRACT_UTC("WORKFLOW_FINISHED")<SYS_EXTRACT_UTC(TO_DATE('wtf','dd.mm.yyyy')) Cost: 254 Bytes: 31 Cardinality: 1 CPU Cost: 34 M IO Cost: 248 Time: 4 
+0

@BoltClock: aw, không thể đặt sql vào cuối danh sách thẻ: -S Vấn đề là oracle cụ thể, không chỉ là câu hỏi sql chung – zerkms

+0

Tôi đoán trình tối ưu hóa không tìm thấy bản ghi (sử dụng chỉ mục) cho nhân viên 159 với trạng thái là 7, 12 hoặc 17, do đó, nó không làm phiền việc đánh giá phần còn lại của truy vấn. Khi bạn loại bỏ kiểm tra trạng thái, một số bản ghi được tìm thấy, vì vậy nó cần đánh giá hàm TO_DATE và gây ra lỗi. Thật khó để nói chắc chắn những gì mà trình tối ưu hóa truy vấn đang thực hiện ... – Sparky

+0

@Sparky: xem đoạn cuối cùng - nếu chúng ta xóa truy vấn "sai" - nó trả về các hàng. Tôi cũng nghĩ như vậy trong một lúc, nhưng ** có ** hồ sơ với các trạng thái được chỉ định – zerkms

Trả lời

3

nó có thể phát hiện ra rằng tất cả các kỷ lục đáp ứng tất cả các điều kiện khác có một trường NULLworkflow_finished.

Và bất kỳ điều gì so với NULL là không xác định nên không cần đánh giá toán hạng khác.

+1

+1 Chỉ cần một điểm nhỏ: bất cứ điều gì so với NULL là không xác định, không sai, mặc dù nó không có sự khác biệt đây. –

7

Nếu tôi ưu hoa quyết định rằng nó không cần phải đánh giá một chức năng, nó sẽ không, do đó, chức năng sẽ không bao giờ ném ngoại lệ:

select 1 from dual where 1 = 1 OR to_date('asdasdasd','asdasdasdas') > sysdate ; 

     1 
---------- 
     1 

Hàm tăng một ngoại lệ duy nhất nếu nó thực sự được đánh giá:

SQL> select 1 from dual where 1 = 1 AND to_date('asdasd','asdas') > sysdate ; 
select 1 from dual where 1 = 1 AND to_date('asdasd','asdas') > sysdate 
                * 
ERROR at line 1: 
ORA-01821: date format not recognized 

Tuy nhiên, nếu phân tích cú pháp có thể quyết định tĩnh rằng các truy vấn không hợp lệ - vì hàm có kiểu sai của các đối số hoặc truy vấn có loại không hợp lệ, sau đó các phân tích cú pháp sẽ nâng cao một ngoại lệ trước khi tôi ưu hoa được một swing vào nó:

SQL> select 1 from dual where 1 = 1 or to_date('asdasdasd',0) > sysdate ; 
select 1 from dual where 1 = 1 or to_date('asdasdasd',0) > sysdate 
                 * 
ERROR at line 1: 
ORA-00932: inconsistent datatypes: expected DATE got NUMBER 


SQL> select 1 from dual where 1 = 1 or to_date('asdasdasd','asdasdasdas') > 42 ; 
select 1 from dual where 1 = 1 or to_date('asdasdasd','asdasdasdas') > 42 
                     * 
ERROR at line 1: 
ORA-00932: inconsistent datatypes: expected DATE got NUMBER 
+0

Mặc dù bạn hoàn toàn chính xác - nó không phải là một câu trả lời. Bởi vì vấn đề là một chút sâu hơn (không phải ở cấp độ vị ngữ, nhưng ở cấp độ toán hạng). Và alexisdm đã đoán nó một cách chính xác. +1 anyway – zerkms

+0

Ah, tôi đã không đọc qua tất cả các "đọc thêm" ý kiến ​​trước khi trả lời :) –

+0

nhưng dù sao bạn đã làm việc tuyệt vời. Thông tin này chắc chắn sẽ hữu ích cho bất kỳ người đọc nào khác. Nếu alexisdm không đặt câu trả lời của mình - tôi sẽ kiểm tra (và sẽ thêm trường hợp gây ra hành vi "lạ") – zerkms