更好(响应时间)查询分页?

时间:2012-12-07 13:43:02

标签: oracle pagination

我正在使用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

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.

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

1 个答案:

答案 0 :(得分: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

取决于您的索引/表格大小,可以节省更多。