2012-12-07 46 views
0

我正在使用Oracle 11g XE。更好的(響應時間)查詢分頁?

「簡單」的問題:哪個更好?查詢A,B或C?我正在嘗試實現查詢結果集分頁的最快響應時間。我的頁面最多將包含20個結果。

答:

SELECT /*+ FIRST_ROWS(20) */ * 
FROM 
    ((SELECT SCORE(1) RANK, F.ID, 1 AS "IsFile" 
    FROM "File" F 
    WHERE CONTAINS("ContentCLOB", 'April 2009', 1) > 0) 
    UNION ALL 
    (SELECT SCORE(2) RANK, C.ID, 0 AS "IsFile" 
    FROM "Claim" C 
    WHERE CONTAINS(C."IdClaim", 'jjkl', 2) > 0)) 
ORDER BY RANK DESC 

B:

((SELECT /*+ FIRST_ROWS(20) */ SCORE(1) RANK, F.ID, 1 AS "IsFile" 
    FROM "File" F 
    WHERE CONTAINS("ContentCLOB", 'April 2009', 1) > 0) 
    UNION ALL 
    (SELECT /*+ FIRST_ROWS(20) */ SCORE(2) RANK, C.ID, 0 AS "IsFile" 
    FROM "Claim" C 
    WHERE CONTAINS(C."IdClaim", 'jjkl', 2) > 0)) 
ORDER BY RANK DESC 

C:

Like B but without the hints. 

唯一的區別在解釋計劃是,查詢有訂貨前一個額外的視圖。

回答

1

將第一行添加到子查詢通常是一個好主意(忽略VIEW步驟,因爲在第一個查詢中有「select .. from()」,這是額外的步驟)。

我認爲以下對你更好,因爲我猜測你的SORT ORDER BY發生在表訪問後。另外你怎麼分頁,因爲我沒有在那裏看到任何rownum的東西(你是否簡化了這種情況?)。

select r, 
     case "IsFile" when 1 then (select id from File f where f.rowid = a.rid) 
     when 0 then (select id from Claim c where c.rowid = a.rid) 
     end id, 
     "IsFile" 
    from (select /*+ first_rows(20) */ score(100) r, rowid rid, 1 AS "IsFile" 
      from File s 
      where contains(ContentCLOB, 'z', 100) > 0 
     union all 
     select /*+ first_rows(20) */ score(1) r, rowid rid, 0 AS "IsFile" 
      from Claim s 
      where contains(IdClaim, 'z', 1) > 0 
      order by r desc) a 
where rownum <= 20; 

最後的情況只有在你需要ID和rowid不夠好時才需要。如繼承人一個小測試:

SQL> set autotrace on 
SQL> select rank, id, "IsFile" 
    2 from (select rank, id, "IsFile", rownum rn 
    3    from (select /*+ FIRST_ROWS(20) */ 
    4      * 
    5      from ((select score(1) rank, f.id, 1 as "IsFile" 
    6        from File f 
    7        where contains(ContentCLOB, 'z', 1) > 0) union all 
    8        (select score(2) rank, c.id, 0 as "IsFile" 
    9        from Claim c 
10        where contains(c.IdClaim, 'z', 2) > 0)) 
11      order by rank desc)) 
12 where rn >= 1 
13  and rownum <= 20 
14/

     RANK   ID IsFile 
---------- ---------- ---------- 
     25  16373   0 
     21  1192   1 
     21  13477   0 
     21  5394   0 
     21  2870   0 
     17  113   1 
     17  19874   0 
     17  1939   1 
     17  1765   1 
     17  2322   1 
     17  3195   1 

     RANK   ID IsFile 
---------- ---------- ---------- 
     17  4248   1 
     17  4346   1 
     17  4183   1 
     17  8444   1 
     17  9040   1 
     17  9395   1 
     17  10502   1 
     17  10131   1 
     17  11027   1 

20 rows selected. 


Execution Plan 
---------------------------------------------------------- 
Plan hash value: 1202090801 

-------------------------------------------------------------------------------------------------- 
| Id | Operation       | Name  | Rows | Bytes | Cost (%CPU)| Time  | 
-------------------------------------------------------------------------------------------------- 
| 0 | SELECT STATEMENT     |    | 20 | 840 |  9 (12)| 00:00:01 | 
|* 1 | COUNT STOPKEY      |    |  |  |   |   | 
|* 2 | VIEW        |    | 24 | 1008 |  9 (12)| 00:00:01 | 
| 3 | COUNT       |    |  |  |   |   | 
| 4 |  VIEW       |    | 24 | 696 |  9 (12)| 00:00:01 | 
| 5 |  SORT ORDER BY     |    | 24 | 696 |  9 (12)| 00:00:01 | 
| 6 |  VIEW       |    | 24 | 696 |  8 (0)| 00:00:01 | 
| 7 |  UNION-ALL     |    |  |  |   |   | 
| 8 |   TABLE ACCESS BY INDEX ROWID| FILE | 10 | 20270 |  4 (0)| 00:00:01 | 
|* 9 |   DOMAIN INDEX    | CTXIDX1  |  |  |  4 (0)| 00:00:01 | 
| 10 |   TABLE ACCESS BY INDEX ROWID| CLAIM | 14 | 28378 |  4 (0)| 00:00:01 | 
|* 11 |   DOMAIN INDEX    | CTXIDX2  |  |  |  4 (0)| 00:00:01 | 
-------------------------------------------------------------------------------------------------- 

Predicate Information (identified by operation id): 
--------------------------------------------------- 

    1 - filter(ROWNUM<=20) 
    2 - filter("RN">=1) 
    9 - access("CTXSYS"."CONTAINS"("CONTENTCLOB",'z',1)>0) 
    11 - access("CTXSYS"."CONTAINS"("R"."IDCLAIM",'z',2)>0) 

Note 
----- 
    - dynamic sampling used for this statement (level=2) 


Statistics 
---------------------------------------------------------- 
     51 recursive calls 
      0 db block gets 
     6506 consistent gets 
      0 physical reads 
      0 redo size 
     760 bytes sent via SQL*Net to client 
     375 bytes received via SQL*Net from client 
      3 SQL*Net roundtrips to/from client 
      1 sorts (memory) 
      0 sorts (disk) 
     20 rows processed 

SQL> select rank, id, "IsFile" 
    2 from (select rank, 
    3     case "IsFile" 
    4      when 1 then 
    5      (select id from File f where f.rowid = a.rid) 
    6      when 0 then 
    7      (select id from Claim c where c.rowid = a.rid) 
    8     end id, "IsFile", rownum r 
    9    from (select /*+ first_rows(20) */ 
10      score(100) rank, rowid rid, 1 as "IsFile" 
11      from File s 
12      where contains(ContentCLOB, 'z', 100) > 0 
13     union all 
14     select /*+ first_rows(20) */ 
15      score(1) rank, rowid rid, 0 as "IsFile" 
16      from Claim s 
17      where contains(IdClaim, 'z', 1) > 0 
18      order by rank desc) a) 
19 where r >= 1 
20  and rownum <= 20 
21/

     RANK   ID IsFile 
---------- ---------- ---------- 
     25  16373   0 
     21  1192   1 
     21  13477   0 
     21  5394   0 
     21  2870   0 
     17  113   1 
     17  19874   0 
     17  1939   1 
     17  1765   1 
     17  2322   1 
     17  3195   1 

     RANK   ID IsFile 
---------- ---------- ---------- 
     17  4248   1 
     17  4346   1 
     17  4183   1 
     17  8444   1 
     17  9040   1 
     17  9395   1 
     17  10502   1 
     17  10131   1 
     17  11027   1 

20 rows selected. 


Execution Plan 
---------------------------------------------------------- 
Plan hash value: 1724352232 

------------------------------------------------------------------------------------------- 
| Id | Operation     | Name  | Rows | Bytes | Cost (%CPU)| Time  | 
------------------------------------------------------------------------------------------- 
| 0 | SELECT STATEMENT   |    | 20 | 840 |  9 (12)| 00:00:01 | 
| 1 | TABLE ACCESS BY USER ROWID | FILE |  1 | 25 |  1 (0)| 00:00:01 | 
| 2 | TABLE ACCESS BY USER ROWID| CLAIM |  1 | 25 |  1 (0)| 00:00:01 | 
|* 3 | COUNT STOPKEY    |    |  |  |   |   | 
|* 4 | VIEW      |    | 24 | 1008 |  9 (12)| 00:00:01 | 
| 5 | COUNT     |    |  |  |   |   | 
| 6 |  VIEW     |    | 24 | 672 |  9 (12)| 00:00:01 | 
| 7 |  SORT ORDER BY   |    | 24 | 48336 |  8 (50)| 00:00:01 | 
| 8 |  UNION-ALL    |    |  |  |   |   | 
|* 9 |  DOMAIN INDEX   | CTXIDX1  | 10 | 20140 |  4 (0)| 00:00:01 | 
|* 10 |  DOMAIN INDEX   | CTXIDX2  | 14 | 28196 |  4 (0)| 00:00:01 | 
------------------------------------------------------------------------------------------- 

Predicate Information (identified by operation id): 
--------------------------------------------------- 

    3 - filter(ROWNUM<=20) 
    4 - filter("R">=1) 
    9 - access("CTXSYS"."CONTAINS"("CONTENTCLOB",'z',100)>0) 
    10 - access("CTXSYS"."CONTAINS"("IDCLAIM",'z',1)>0) 

Note 
----- 
    - dynamic sampling used for this statement (level=2) 


Statistics 
---------------------------------------------------------- 
     51 recursive calls 
      0 db block gets 
     216 consistent gets 
      0 physical reads 
      0 redo size 
     760 bytes sent via SQL*Net to client 
     375 bytes received via SQL*Net from client 
      3 SQL*Net roundtrips to/from client 
      1 sorts (memory) 
      0 sorts (disk) 
     20 rows processed 

相同的結果,但要注意的IO: 原:

6506 consistent gets 

延遲,直到排序後的表訪問:

216 consistent gets 

取決於你的索引/表格大小,節省的可能會更多。