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

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

子:

 Like B but without the hints.

Explain Plans の唯一の違いは、クエリ A には注文前に追加のビューがあることです。

4

1 に答える 1

1

通常、サブクエリに最初の行を追加することをお勧めします(最初のクエリには追加のステップである「select .. from()」があるため、VIEWステップは無視してください)。

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

インデックス/テーブルのサイズによっては、大幅な節約になる可能性があります。

于 2012-12-07T17:12:30.767 に答える