将第一行添加到子查询通常是一个好主意(忽略 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
根据您的索引/表大小,节省的费用可能会更多。