设为首页 收藏本站
查看: 372|回复: 0

[经验分享] Oracle查询转换之视图合并

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2015-10-8 07:56:08 | 显示全部楼层 |阅读模式
                      一.简单视图合并:指针对那些不含外连接,以及所带视图定义sql语句中不含distinct,group by等聚合函数的目标sql的视图合并。
1
2
3
4
5
create or replace view view_1 as
SELECT t2.prod_id
  FROM sales t2, customers t3
WHERE t2.cust_id = t3.cust_id
   AND t3.cust_gender = 'M';



视图合并:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
  SELECT t1.prod_id, t1.prod_name
     FROM products t1,view_1
    WHERE t1.prod_id = view_1.prod_id
  4       AND t1.prod_list_price > 1000;
Execution Plan
----------------------------------------------------------
Plan hash value: 3569238377
-----------------------------------------------------------------------------------------------------------------------
| Id  | Operation       | Name      | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
-----------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT       |      |   213K|    10M|   648(2)| 00:00:08 |       |       |
|*  1 |  HASH JOIN       |      |   213K|    10M|   648(2)| 00:00:08 |       |       |
|*  2 |   VIEW       | index$_join$_004     | 27750 |   189K|   119(1)| 00:00:02 |       |       |
|*  3 |    HASH JOIN       |      |       |       |    |      |       |       |
|   4 |     BITMAP CONVERSION TO ROWIDS|      | 27750 |   189K|     2(0)| 00:00:01 |       |       |
|*  5 |      BITMAP INDEX SINGLE VALUE | CUSTOMERS_GENDER_BIX |       |       |    |      |       |       |
|   6 |     INDEX FAST FULL SCAN       | CUSTOMERS_PK      | 27750 |   189K|   145(0)| 00:00:02 |       |       |
|*  7 |   HASH JOIN       |      |   213K|  9160K|   528(2)| 00:00:07 |       |       |
|*  8 |    TABLE ACCESS FULL       | PRODUCTS      |    17 |   595 |     3(0)| 00:00:01 |       |       |
|   9 |    PARTITION RANGE ALL       |      |   918K|  8075K|   523(1)| 00:00:07 |     1 |    28 |
|  10 |     TABLE ACCESS FULL       | SALES      |   918K|  8075K|   523(1)| 00:00:07 |     1 |    28 |
-----------------------------------------------------------------------------------------------------------------------



禁用视图合并:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
      SELECT /*+ no_merge(view_1) */
         t1.prod_id, t1.prod_name
          FROM products t1, view_1
         WHERE t1.prod_id = view_1.prod_id
              AND t1.prod_list_price > 1000 ;
10156 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 2109926904
-------------------------------------------------------------------------------------------------------------------------
| Id  | Operation | Name | Rows| Bytes | Cost (%CPU)| Time| Pstart| Pstop |
-------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT ||   213K|  9992K|   649   (2)| 00:00:08 |||
|*  1 |  HASH JOIN ||   213K|  9992K|   649   (2)| 00:00:08 |||
|*  2 |   TABLE ACCESS FULL | PRODUCTS|    17 |   595 |     3   (0)| 00:00:01 |||
|   3 |   VIEW | VIEW_1|   918K|    11M|   644   (2)| 00:00:08 |||
|*  4 |    HASH JOIN ||   918K|    14M|   644   (2)| 00:00:08 |||
|*  5 |     VIEW | index$_join$_004| 27750 |   189K|   119   (1)| 00:00:02 |||
|*  6 |      HASH JOIN ||||     ||||
|   7 |       BITMAP CONVERSION TO ROWIDS|| 27750 |   189K|     2   (0)| 00:00:01 |||
|*  8 |        BITMAP INDEX SINGLE VALUE | CUSTOMERS_GENDER_BIX |||     ||||
|   9 |       INDEX FAST FULL SCAN | CUSTOMERS_PK | 27750 |   189K|   145   (0)| 00:00:02 |||
|  10 |     PARTITION RANGE ALL  ||   918K|  8075K|   523   (1)| 00:00:07 |     1 |    28 |
|  11 |      TABLE ACCESS FULL | SALES|   918K|  8075K|   523   (1)| 00:00:07 |     1 |    28 |
-------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - access("T1"."PROD_ID"="VIEW_1"."PROD_ID")
   2 - filter("T1"."PROD_LIST_PRICE">1000)
   4 - access("T2"."CUST_ID"="T3"."CUST_ID")
   5 - filter("T3"."CUST_GENDER"='M')
   6 - access(ROWID=ROWID)
   8 - access("T3"."CUST_GENDER"='M')



一般来说,如果oracle并没有选择对带视图的目标sql执行合并的话,那么该sql的执行计划中就会见到“view”关键字,并且该关键字所对应的Name列的值就是该视图的名称.
千万 不要认为只要执行计划中出现了VIEW关键字就表明oracle一定没有做视图合并,这是不一定的,因为还存在着其他的一些特殊情形,在这些情形下,即使oracle做了视图合并,其对应执行计划中叶会出现VIEW关键字,比如inde_jion后面出现的临时视图,对于符合简单条件视图合并条件的目标sql。oracle始终会对其进行视图合并,不管成本。
二:外连接视图合并:是指针对那些使用了外连接,以及所带视图的视图定义sql语句中不含distinct,group by等聚合函数的目标sql的视图合并。这里使用外连接的含义指外部查询的表和视图之间使用了外连接,或该视图的视图定义sql语句中使用了外连接。外连接视图的限制:当目标视图和外部查询的表做外连接时,该目标视图可以做外连接视图合并的前提条件是,要么该视图被作为外连接的驱动表,要么该视图虽然被作为外连接的被驱动表但它的视图定义的sql语句中指包含一个表。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
   SELECT t1.prod_id, t1.prod_name
     FROM products t1,view_2
  3      WHERE t1.prod_id(+) = view_2.prod_id;
594703 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 523667190
------------------------------------------------------------------------------------------------------------------------
| Id  | Operation| Name       | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT|       |   918K|    40M|   649 (2)| 00:00:08 |       |       |
|*  1 |  HASH JOIN RIGHT OUTER|       |   918K|    40M|   649 (2)| 00:00:08 |       |       |
|   2 |   TABLE ACCESS FULL| PRODUCTS       |    72 |  2160 |     3 (0)| 00:00:01 |       |       |
|*  3 |   HASH JOIN|       |   918K|    14M|   644 (2)| 00:00:08 |       |       |
|*  4 |    VIEW | index$_join$_004     | 27750 |   189K|   119 (1)| 00:00:02 |       |       |
|*  5 |     HASH JOIN|       |       |       |    |       |       |       |
|   6 |      BITMAP CONVERSION TO ROWIDS|       | 27750 |   189K|     2 (0)| 00:00:01 |       |       |
|*  7 |       BITMAP INDEX SINGLE VALUE | CUSTOMERS_GENDER_BIX |       |       |    |       |       |       |
|   8 |      INDEX FAST FULL SCAN| CUSTOMERS_PK       | 27750 |   189K|   145 (0)| 00:00:02 |       |       |
|   9 |    PARTITION RANGE ALL|       |   918K|  8075K|   523 (1)| 00:00:07 |     1 |    28 |
|  10 |     TABLE ACCESS FULL| SALES        |   918K|  8075K|   523 (1)| 00:00:07 |     1 |    28 |
------------------------------------------------------------------------------------------------------------------------



更改驱动表后,没有进行视图合并(且视图定义sql有2个表关联):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
SELECT t1.prod_id, t1.prod_name
     FROM products t1,view_2
  3      WHERE t1.prod_id = view_2.prod_id(+)
  4  ;
  5  
   SELECT t1.prod_id, t1.prod_name
     FROM products t1,view_2
  3      WHERE t1.prod_id = view_2.prod_id(+)
  4  ;
594703 rows selected
Execution Plan
----------------------------------------------------------
Plan hash value: 2735117096
-------------------------------------------------------------------------------------------------------------------------
| Id  | Operation | Name | Rows| Bytes | Cost (%CPU)| Time| Pstart| Pstop |
-------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT ||   918K|    37M|   649   (2)| 00:00:08 |||
|*  1 |  HASH JOIN OUTER ||   918K|    37M|   649   (2)| 00:00:08 |||
|   2 |   TABLE ACCESS FULL | PRODUCTS|    72 |  2160 |     3   (0)| 00:00:01 |||
|   3 |   VIEW | VIEW_2|   918K|    11M|   644   (2)| 00:00:08 |||
|*  4 |    HASH JOIN ||   918K|    14M|   644   (2)| 00:00:08 |||
|*  5 |     VIEW | index$_join$_004| 27750 |   189K|   119   (1)| 00:00:02 |||
|*  6 |      HASH JOIN ||||     ||||
|   7 |       BITMAP CONVERSION TO ROWIDS|| 27750 |   189K|     2   (0)| 00:00:01 |||
|*  8 |        BITMAP INDEX SINGLE VALUE | CUSTOMERS_GENDER_BIX |||     ||||
|   9 |       INDEX FAST FULL SCAN | CUSTOMERS_PK | 27750 |   189K|   145   (0)| 00:00:02 |||
|  10 |     PARTITION RANGE ALL  ||   918K|  8075K|   523   (1)| 00:00:07 |     1 |    28 |
|  11 |      TABLE ACCESS FULL | SALES|   918K|  8075K|   523   (1)| 00:00:07 |     1 |    28 |
-------------------------------------------------------------------------------------------------------------------------



当视图的定义sql中只有一个表:
可以进行视图合并:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
create or replace view view_3 as
SELECT t2.prod_id
  FROM sales t2
WHERE t2.amount_sold>700
   SELECT t1.prod_id, t1.prod_name
     FROM products t1,view_3
  3      WHERE t1.prod_id = view_3.prod_id(+);
39317 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 1313708566
-------------------------------------------------------------------------------------------------
| Id  | Operation     | Name| Rows| Bytes | Cost (%CPU)| Time| Pstart| Pstop |
-------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     ||   560K|    20M|   531   (2)| 00:00:07 |||
|*  1 |  HASH JOIN OUTER     ||   560K|    20M|   531   (2)| 00:00:07 |||
|   2 |   TABLE ACCESS FULL  | PRODUCTS |    72 |  2160 |     3   (0)| 00:00:01 |||
|   3 |   PARTITION RANGE ALL||   560K|  4922K|   526   (2)| 00:00:07 |     1 |    28 |
|*  4 |    TABLE ACCESS FULL | SALES|   560K|  4922K|   526   (2)| 00:00:07 |     1 |    28 |
-------------------------------------------------------------------------------------------------



三.复杂视图合并:
复杂视图合并(Complex View Mergin)是针对那些所带视图的视图定义sql语句中中含有group by或distinct的目标sql的视图合并.
    和简单视图合并,外连接视图合并一样,对这种视图定义sql语句中含有group by或distinct的复杂视图做视图合并也同样意味着要把其定义sql语句拆开,并把其中的基表和外部查询中的表合并,这通常意味着上述视图定义sql语句中的group by或distinct操作会被推迟执行,也就是说,这种情况下通常会先做表连接,再做group by 或distinct操作,而不是像未做复杂视图合并时那样在视图内部做完group by或distinct操作,然后才和外部查询中的表做表连接。

    复杂视图合并所对应的group by 或distinct操作延迟,并不一定总是能带来执行效率以及性能上的提升。例如,如果group by或distinct操作能过滤掉绝大部分的数据且表连接并不能有效过滤数据的话,那么先在视图内部做group by或者distinct操作,然后和外部查询中的表做表连接的执行效率会更高些,但是如果表连接能过滤绝大部分数据而group by或distinct操作并不能有效过滤数据的话,那么先做表连接,在做group by或distinct的操作的执行效率显然会更好一些。

    正是因为复杂视图合并并不一定总是能带来目标sql的执行效率及性能上得提升,所以oracle 10g及以后的版本中,对应复杂视图的合并,只有当经过复杂视图合并后等价sql的成本值小于原sql的成本值时,oracle才会对目标sql执行复杂sql的视图合并。



SQL> set lines 200 pagesize 1000
SELECT t1.cust_id, t1.cust_last_name
  FROM customers t1, products t2, view_3 t3
WHERE t1.cust_id = t3.cust_id
   AND t2.prod_id = t3.prod_id
   AND t3.total > 1000
   AND t2.prod_category = 'Hardware'
   AND t1.cust_year_of_birth = 1977
  7    8     AND t1.cust_marital_status = 'married';

32 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 3286306050
--------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                         | Name                  | Rows  | Bytes | Cost (%CPU)| Time         | Pstart| Pstop |
--------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                 |                         |    61 |  5002 |   544   (2)| 00:00:07 |         |         |
|*  1 |  FILTER                          |                         |         |         |              |          |         |         |
|   2 |   HASH GROUP BY                  |                         |    61 |  5002 |   544   (2)| 00:00:07 |         |         |
|*  3 |    HASH JOIN                         |                         |  1201 | 98482 |   543   (2)| 00:00:07 |         |         |
|   4 |     TABLE ACCESS BY INDEX ROWID  | PRODUCTS                 |    14 |   462 |     3   (0)| 00:00:01 |         |         |
|*  5 |      INDEX RANGE SCAN                 | PRODUCTS_PROD_CAT_IX  |    14 |         |     1   (0)| 00:00:01 |         |         |
|*  6 |     HASH JOIN                         |                         |  6007 |   287K|   540   (2)| 00:00:07 |         |         |
|   7 |      TABLE ACCESS BY INDEX ROWID | CUSTOMERS                 |    46 |  1610 |    13   (0)| 00:00:01 |         |         |
|   8 |       BITMAP CONVERSION TO ROWIDS|                         |         |         |              |          |         |         |
|   9 |        BITMAP AND                 |                         |         |         |              |          |         |         |
|* 10 |         BITMAP INDEX SINGLE VALUE| CUSTOMERS_YOB_BIX         |         |         |              |          |         |         |
|* 11 |         BITMAP INDEX SINGLE VALUE| CUSTOMERS_MARITAL_BIX |         |         |              |          |         |         |
|  12 |      PARTITION RANGE ALL         |                         |   918K|    12M|   525   (2)| 00:00:07 |     1 |    28 |
|  13 |       TABLE ACCESS FULL          | SALES                 |   918K|    12M|   525   (2)| 00:00:07 |     1 |    28 |
--------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter(SUM("AMOUNT_SOLD")>1000)
   3 - access("T2"."PROD_ID"="PROD_ID")
   5 - access("T2"."PROD_CATEGORY"='Hardware')
   6 - access("T1"."CUST_ID"="CUST_ID")
  10 - access("T1"."CUST_YEAR_OF_BIRTH"=1977)
  11 - access("T1"."CUST_MARITAL_STATUS"='married')
Statistics
----------------------------------------------------------
          8  recursive calls
          0  db block gets
       1914  consistent gets
       1619  physical reads
          0  redo size
       1461  bytes sent via SQL*Net to client
        546  bytes received via SQL*Net from client
          4  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
         32  rows processed

SELECT /*+ no_merge(t3) */t1.cust_id, t1.cust_last_name
  FROM customers t1, products t2, view_3 t3
WHERE t1.cust_id = t3.cust_id
   AND t2.prod_id = t3.prod_id
   AND t3.total > 1000
   AND t2.prod_category = 'Hardware'
   AND t1.cust_year_of_birth = 1977
  8     AND t1.cust_marital_status = 'married';
32 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 215761499
---------------------------------------------------------------------------------------------------------------
| Id  | Operation                       | Name              | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
---------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT               |              |     1 |    70 |   550        (6)| 00:00:07 |       |       |
|   1 |  NESTED LOOPS                       |              |     1 |    70 |   550        (6)| 00:00:07 |       |       |
|   2 |   NESTED LOOPS                       |              |     1 |    70 |   550        (6)| 00:00:07 |       |       |
|   3 |    NESTED LOOPS                |              |     1 |    47 |   549        (6)| 00:00:07 |       |       |
|   4 |     VIEW                       | VIEW_3       |     1 |    26 |   548        (6)| 00:00:07 |       |       |
|*  5 |      FILTER                       |              |       |       |            |              |       |       |
|   6 |       HASH GROUP BY               |              |     1 |    14 |   548        (6)| 00:00:07 |       |       |
|   7 |        PARTITION RANGE ALL     |              |   918K|    12M|   525        (2)| 00:00:07 |     1 |    28 |
|   8 |         TABLE ACCESS FULL      | SALES              |   918K|    12M|   525        (2)| 00:00:07 |     1 |    28 |
|*  9 |     TABLE ACCESS BY INDEX ROWID| PRODUCTS     |     1 |    21 |     1        (0)| 00:00:01 |       |       |
|* 10 |      INDEX UNIQUE SCAN               | PRODUCTS_PK  |     1 |       |     0        (0)| 00:00:01 |       |       |
|* 11 |    INDEX UNIQUE SCAN               | CUSTOMERS_PK |     1 |       |     0        (0)| 00:00:01 |       |       |
|* 12 |   TABLE ACCESS BY INDEX ROWID  | CUSTOMERS    |     1 |    23 |     1        (0)| 00:00:01 |       |       |
---------------------------------------------------------------------------------------------------------------

                   


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-124004-1-1.html 上篇帖子: Oracle各个版本警告日志的位置 下篇帖子: 通过bbed修复ora-01190错误 Oracle
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表