truy vấn của bạn thực hiện ba nhiệm vụ:
1) tìm nạp dữ liệu cho cả các tập con (12 và 14)
2) tham gia các dữ liệu và
3) vượt qua các kết quả để khách hàng
Lưu ý rằng quyền truy cập chỉ mục (mà bạn nghi ngờ gây ra sự cố) chỉ liên quan đến bước 1. Vì vậy, để có được ấn tượng tốt hơn điều đầu tiên là nhận ra sự phân bố thời gian trôi qua giữa ba bước. Điều này có thể được thực hiện sử dụng SQL * Plus (Tôi đang sử dụng các dữ liệu được tạo giống như trong câu trả lời trước của tôi)
Data Access
Như bàn của tôi không có chỉ số, biểu diễn một count (*) thực hiện một FULL TABLE SCAN. Vì vậy, trong một trường hợp xấu nhất một hai lần thời gian được sử dụng để có được dữ liệu.
SQL> set timi on
SQL> set autotrace on
SQL> select count(*) from mytab;
COUNT(*)
----------
20000
Elapsed: 00:00:01.13
Execution Plan
----------------------------------------------------------
Plan hash value: 3284627250
--------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
--------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 5472 (1)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | TABLE ACCESS FULL| MYTAB | 20000 | 5472 (1)| 00:00:01 |
--------------------------------------------------------------------
FTS sẵn sàng sau khoảng một giây, để nhận được cả hai nhóm aprox. hai giây trôi qua.
THAM GIA
Các trôi qua thời gian để tham gia lon bằng mô phỏng với một CTAS của truy vấn tham gia.
SQL> create table myRes as
2 select a.SessionOrder rn0, b.SessionOrder rn1
3 from myTab a join myTab b on a.SessionOrder > b.SessionOrder and
4 a.something = 12 and b.something = 14;
Table created.
Elapsed: 00:00:23.65
Tham gia trả về gần 50M hàng (do lớn hơn điều kiện) và mất khoảng 21 giây (tôi trừ 2 giây để truy cập dữ liệu).
PASS dữ liệu cho khách hàng
Chúng tôi sử dụng tùy chọn set autotrace traceonly
để ngăn chặn đầu ra của các truy vấn trên màn hình của khách hàng, nhưng dữ liệu được chuyển giao, vì vậy chúng tôi có thể đo thời gian. (Nếu bạn làm cho kết quả trên màn hình, thời gian sẽ còn cao hơn nhiều)
SQL> SET ARRAYSIZE 5000
SQL> set autotrace traceonly
SQL> select a.SessionOrder rn0, b.SessionOrder rn1
2 from myTab a join myTab b on a.SessionOrder > b.SessionOrder and
3 a.something = 12 and b.something = 14;
49995000 rows selected.
Elapsed: 00:03:03.89
Execution Plan
----------------------------------------------------------
Plan hash value: 2857240533
-----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 49M| 667M| 11077 (2)| 00:00:01 |
| 1 | MERGE JOIN | | 49M| 667M| 11077 (2)| 00:00:01 |
| 2 | SORT JOIN | | 10000 | 70000 | 5473 (1)| 00:00:01 |
|* 3 | TABLE ACCESS FULL| MYTAB | 10000 | 70000 | 5472 (1)| 00:00:01 |
|* 4 | SORT JOIN | | 10000 | 70000 | 5473 (1)| 00:00:01 |
|* 5 | TABLE ACCESS FULL| MYTAB | 10000 | 70000 | 5472 (1)| 00:00:01 |
-----------------------------------------------------------------------------
Dưới đây là thời gian nhất dành khoảng 2:40 phút
Tóm tắt
Vì vậy, trong kịch bản từ tổng số 3 phút + chỉ khoảng 2 giây là chi tiêu cho truy cập dữ liệu (hoặc khoảng 1%). Thậm chí nếu bạn cắt quyền truy cập dữ liệu xuống một phần mười - bạn sẽ thấy hầu như không có sự khác biệt. Vấn đề nằm trong sự tham gia và thậm chí nhiều hơn trong việc chuyển dữ liệu cho khách hàng.
Khi Index có thể giúp
Và tất nhiên nó phụ thuộc ...
Trong một trường hợp rất đặc biệt, nơi bạn có một bảng rất lớn với dữ liệu rất ít với something in (12,14)
bạn có thể lợi nhuận từ chỉ mục được xác định trên một cái gì đó VÀ SessionOrder. Điều này chỉ cho phép sử dụng chỉ số chỉ truy cập vào bỏ qua bảng dữ liệu.
Kế hoạch thực hiện cho thấy nó đang hoạt động như thế nào? Mỗi truy vấn phụ tìm bao nhiêu hàng? (Tại sao bạn sử dụng các truy vấn phụ thay vì chỉ tham gia các bảng? Và điều này không giống như cú pháp Oracle tại thời điểm này). –
Đây không phải là truy vấn hợp lệ. Các bí danh của bảng không được định nghĩa trong phạm vi 'ON i_0.rn> i_1.rn' –
Tôi đồng ý với Alex, điều này chắc chắn không phải cú pháp Oracle. Điều đó nói rằng, đây gần như là một tham gia Descartes. Bạn có thực sự có ý định tham gia mỗi hàng ít hơn i_o.rn để i_o? Ví dụ, SQL này trả về 4.950 hàng: với aset như (chọn rownum r từ dba_objects nơi rownum <101) chọn a.r, b.r từ aset a tham gia bên trong aset b trên a.r> b.r. –