0

我正在使用 Oracle 11g XE。

“简单”的问题:哪个更好?查询 A、B 还是 C?我正在尝试实现对结果集分页查询的最快响应时间。我的页面最多包含 20 个结果。

A:

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

乙:

  ((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.

解释计划的唯一区别是查询 A 在订购前有一个额外的视图。

4

1 回答 1

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: original:

   6506  consistent gets

将表访问延迟到排序之后:

    216  consistent gets

根据您的索引/表大小,节省的费用可能会更多。

于 2012-12-07T17:12:30.767 回答