通常、サブクエリに最初の行を追加することをお勧めします(最初のクエリには追加のステップである「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
インデックス/テーブルのサイズによっては、大幅な節約になる可能性があります。