2010-04-29 30 views
6

Tôi đang làm việc với một oracle DB cố gắng điều chỉnh một số truy vấn và tôi không hiểu tại sao làm việc một mệnh đề cụ thể theo một cách cụ thể có tác động mạnh đến hiệu suất truy vấn. Dưới đây là một phiên bản performant của truy vấn tôi đang làmTại sao các truy vấn dường như tương tự này lại có thời gian chạy khác nhau đáng kể?

select * from 
(
    select a.*, rownum rn from 
    ( 
     select * 
     from table_foo 
    ) a where rownum <= 3 
) where rn >= 2 

Truy vấn tương tự bằng cách thay thế hai dòng cuối cùng với điều này

) a where rownum >=2 rownum <= 3 
) 

Thực hiện khủng khiếp. Một số đơn đặt hàng có cường độ kém hơn

) a where rownum between 2 and 3 
) 

cũng hoạt động khủng khiếp. Tôi không hiểu phép thuật từ truy vấn đầu tiên và cách áp dụng nó cho các truy vấn tương tự khác.

+3

Bạn có thể chạy phân tích truy vấn ('EXPLAIN PLAIN', http://download.oracle.com/docs/cd/B19306_01/server.102/b14211/ex_plan.htm) để xem cách DBMS chạy truy vấn. – outis

+0

Như một lưu ý phụ, tại sao 'select *' khi bạn có thể đơn giản 'select * từ (chọn a. *, Rownum rn từ table_foo a nơi rownum <= 3) trong đó rn> = 2'? –

Trả lời

4

Sự hiểu biết của tôi là việc phân bổ lại xảy ra sau (hoặc 'as') hàng được chọn, vì vậy bất kỳ truy vấn 'ROWNUM> = n' nào với n lớn hơn 1 sẽ gây ra sự cố. Điều được giải thích cho tôi là hàng đầu tiên được xem xét; nó là rownum 1, do đó, nó không đáp ứng các tiêu chí và được vứt bỏ. Hàng tiếp theo được xem xét; nó sẽ vẫn là rownum 1 kể từ khi tập kết quả trống, và nó không đáp ứng các tiêu chí và bị vứt bỏ. Quá trình này tiếp tục cho đến khi tất cả các hàng đã được đọc và bị từ chối.

Truy vấn chạy dài có thực sự tạo ra bất kỳ dữ liệu nào không? Hay bạn luôn giết nó trước khi nó hoàn thành?

+0

Câu trả lời sẽ là có - nếu anh ta có ROWNUM> = 2 (tức là bất kỳ biến vị ngữ nào đánh giá thành FALSE khi ROWNUM = 1) truy vấn sẽ chỉ chạy qua toàn bộ tập dữ liệu và không trả về gì cả. –

+0

Tôi thực sự đã thử điều này và có, truy vấn sẽ chỉ chạy cho đến khi tất cả các hàng bị cạn kiệt và không trả lại gì cả. Vì vậy, về bản chất, các truy vấn được đề cập không giống nhau. –

1

ROWNUM là một pseudocolumn (không phải là cột thực) có sẵn trong truy vấn. ROWNUM sẽ được gán các số 1, 2, 3, 4, ... N, trong đó N là số hàng trong tập hợp ROWNUM được sử dụng với. Trong trường hợp đầu tiên, bạn đang cắt số hàng ngay lập tức khỏi con dơi, và trong phần thứ hai, bạn phải tìm mọi thứ để cắt bỏ những thứ lớn hơn 2.

Các vấn đề liên quan