我正在使用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在订购之前有一个额外的视图。
答案 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
取决于您的索引/表格大小,可以节省更多。