测试发现,Oracle不支持全外连接的查询重写,即使物化视图和查询语句完全匹配。
继续测试对外连接物化视图是否可以重写。
上一篇测试发现即使查询完全匹配,全外连接也无法利用物化视图进行查询重写,那么问题是FULL OUTER JOIN这种写法导致的,还是外连接本身的特殊性导致的。
SQL> SET AUTOT ON
SQL> SELECT T1.ID, T2.ID
2 FROM T1, T2
3 WHERE T1.ID = T2.ID (+);
ID ID
--------------------
2 2
3 3
4 4
5 5
6 6
7 7
8 8
1
0
已选择9行。
执行计划
----------------------------------------------------------
Plan hash value: 1823443478
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 9 | 234 | 9 (12)| 00:00:01 |
|* 1 | HASH JOIN OUTER | | 9 | 234 | 9 (12)| 00:00:01 |
| 2 | TABLE ACCESS FULL| T1 | 9 | 117 | 4 (0)| 00:00:01 |
| 3 | TABLE ACCESS FULL| T2 | 9 | 117 | 4 (0)| 00:00:01 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("T1"."ID"="T2"."ID"(+))
Note
-----
- dynamic sampling used for this statement (level=2)
统计信息
----------------------------------------------------------
0 recursive calls
0 db block gets
15 consistent gets
0 physical reads
0 redo size
716 bytes sent via SQL*Net to client
520 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
9 rows processed
SQL> CREATE MATERIALIZED VIEW MV_T12
2 ENABLE QUERY REWRITE AS
3 SELECT T1.ID ID1, T2.ID ID2
4 FROM T1, T2
5 WHERE T1.ID = T2.ID (+);
实体化视图已创建。
SQL> SELECT T1.ID, T2.ID
2 FROM T1, T2
3 WHERE T1.ID = T2.ID (+);
ID ID
--------------------
2 2
3 3
4 4
5 5
6 6
7 7
8 8
1
0
已选择9行。
执行计划
----------------------------------------------------------
Plan hash value: 183449623
---------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 9 | 234 | 3 (0)| 00:00:01 |
| 1 | MAT_VIEW REWRITE ACCESS FULL| MV_T12 | 9 | 234 | 3 (0)| 00:00:01 |
---------------------------------------------------------------------------------------
Note
-----
- dynamic sampling used for this statement (level=2)
统计信息
----------------------------------------------------------
13 recursive calls
0 db block gets
24 consistent gets
1 physical reads
0 redo size
723 bytes sent via SQL*Net to client
520 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
9 rows processed
对于普通外连接是可以进行查询重写的,检查是否是SQL标准语法导致的问题:
SQL> SELECT T1.ID, T2.ID
2 FROM T1 LEFT OUTER JOIN T2
3 ON T1.ID = T2.ID;
ID ID
--------------------
2 2
3 3
4 4
5 5
6 6
7 7
8 8
1
0
已选择9行。
执行计划
----------------------------------------------------------
Plan hash value: 183449623
---------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 9 | 234 | 3 (0)| 00:00:01 |
| 1 | MAT_VIEW REWRITE ACCESS FULL| MV_T12 | 9 | 234 | 3 (0)| 00:00:01 |
---------------------------------------------------------------------------------------
Note
-----
- dynamic sampling used for this statement (level=2)
统计信息
----------------------------------------------------------
10 recursive calls
0 db block gets
24 consistent gets
0 physical reads
0 redo size
723 bytes sent via SQL*Net to client
520 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
9 rows processed
和标准语法也没有关系,检查全外连接能否使用这个物化视图进行查询重写:
SQL> SELECT T1.ID, T2.ID
2 FROM T1 FULL OUTER JOIN T2
3 ON T1.ID = T2.ID;
ID ID
--------------------
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9
10
1
0
已选择11行。
执行计划
----------------------------------------------------------
Plan hash value: 53297166
----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 9 | 234 | 9 (12)| 00:00:01 |
| 1 | VIEW | VW_FOJ_0 | 9 | 234 | 9 (12)| 00:00:01 |
|* 2 | HASH JOIN FULL OUTER| | 9 | 234 | 9 (12)| 00:00:01 |
| 3 | TABLE ACCESS FULL | T1 | 9 | 117 | 4 (0)| 00:00:01 |
| 4 | TABLE ACCESS FULL | T2 | 9 | 117 | 4 (0)| 00:00:01 |
----------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("T1"."ID"="T2"."ID")
Note
-----
- dynamic sampling used for this statement (level=2)
统计信息
----------------------------------------------------------
7 recursive calls
0 db block gets
31 consistent gets
0 physical reads
0 redo size
733 bytes sent via SQL*Net to client
520 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
11 rows processed
SQL> SELECT /*+ REWRITE (MV_T12) */ T1.ID, T2.ID
2 FROM T1 FULL OUTER JOIN T2
3 ON T1.ID = T2.ID;
ID ID
--------------------
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9
10
1
0
已选择11行。
执行计划
----------------------------------------------------------
Plan hash value: 53297166
----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 9 | 234 | 9 (12)| 00:00:01 |
| 1 | VIEW | VW_FOJ_0 | 9 | 234 | 9 (12)| 00:00:01 |
|* 2 | HASH JOIN FULL OUTER| | 9 | 234 | 9 (12)| 00:00:01 |
| 3 | TABLE ACCESS FULL | T1 | 9 | 117 | 4 (0)| 00:00:01 |
| 4 | TABLE ACCESS FULL | T2 | 9 | 117 | 4 (0)| 00:00:01 |
----------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("T1"."ID"="T2"."ID")
Note
-----
- dynamic sampling used for this statement (level=2)
统计信息
----------------------------------------------------------
7 recursive calls
0 db block gets
31 consistent gets
0 physical reads
0 redo size
733 bytes sent via SQL*Net to client
520 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
11 rows processed
SQL> SELECT /*+ NO_NATIVE_FULL_OUTER_JOIN */ T1.ID, T2.ID
2 FROM T1 FULL OUTER JOIN T2
3 ON T1.ID = T2.ID;
ID ID
--------------------
2 2
3 3
4 4
5 5
6 6
7 7
8 8
1
0
10
9
已选择11行。
执行计划
----------------------------------------------------------
Plan hash value: 665903394
-----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 18 | 468 | 12 (9)| 00:00:01 |
| 1 | VIEW | | 18 | 468 | 12 (9)| 00:00:01 |
| 2 | UNION-ALL | | | | | |
| 3 | MAT_VIEW REWRITE ACCESS FULL| MV_T12 | 9 | 234 | 3 (0)| 00:00:01 |
|* 4 | HASH JOIN ANTI | | 9 | 234 | 9 (12)| 00:00:01 |
| 5 | TABLE ACCESS FULL | T2 | 9 | 117 | 4 (0)| 00:00:01 |
| 6 | TABLE ACCESS FULL | T1 | 9 | 117 | 4 (0)| 00:00:01 |
-----------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
4 - access("T1"."ID"="T2"."ID")
Note
-----
- dynamic sampling used for this statement (level=2)
统计信息
----------------------------------------------------------
22 recursive calls
0 db block gets
70 consistent gets
0 physical reads
0 redo size
733 bytes sent via SQL*Net to client
520 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
11 rows processed
直接利用REWRITE提示,Oracle不会利用物化视图进行重新,但是如果利用NO_NATIVE_FULL_OUTER_JOIN提示,那么Oracle会利用创建的物化视图进行查询重写。
看来问题和metalink文档Bug 7032300描述的现象基本一致,看来这个bug在11.2中仍然没有完全解决。