查询转换

  1. 视图合并,视图合并是一种能将内嵌或存储式视图展开为能够独立分析或者与查询剩余部分合成总体执行计划的独立查询的转换,改写后的语句基本上不包含视图。视图合并常常发生在当外部查询块的谓语包括下列项的时候。

    能够在另一个查询块的索引中使用的列

    能够在另一个查询块的分区截断中使用的列

    在一个联结视图中能够限制返回行数的条件

    .

  2. select * from orders o,(select sales_rep_id from orders) o_view where
    o.sales_rep_id=o_view.sales_rep_id(+) and o.order_total>10000
    Plan hash value: 1066515912
    -------------------------------------------------------------------------------------------------
    | Id  | Operation    | Name       | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
    -------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT   |        |      1 | |    368 |00:00:00.01 |      81 |
    |   1 |  NESTED LOOPS OUTER|        |      1 |    635 |    368 |00:00:00.01 |      81 |
    |*  2 |   TABLE ACCESS FULL| ORDERS       |      1 |    101 |     67 |00:00:00.01 |      32 |
    |*  3 |   INDEX RANGE SCAN | ORD_SALES_REP_IX |     67 |      6 |    341 |00:00:00.01 |      49 |
    -------------------------------------------------------------------------------------------------
    Predicate Information (identified by operation id):
    ---------------------------------------------------
      2 - filter("O"."ORDER_TOTAL">10000)
       3 - access("O"."SALES_REP_ID"="SALES_REP_ID")
           filter("SALES_REP_ID" IS NOT NULL)
    23 rows selected

    不视图合并:

  3. select /*+ no_merge(o_view) */* from orders o,(select sales_rep_id from
    orders) o_view where o.sales_rep_id=o_view.sales_rep_id(+) and
    o.order_total>10000
    Plan hash value: 2722607751
    -------------------------------------------------------------------------------------------------------------------
    | Id  | Operation     | Name   | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
    -------------------------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT    |      |     1 |        |    368 |00:00:00.01 |     37 |       |       |   |
    |*  1 |  HASH JOIN OUTER    |      |     1 |    635 |    368 |00:00:00.01 |     37 |  1034K|  1034K|  879K (0)|
    |*  2 |   TABLE ACCESS FULL | ORDERS |     1 |    101 |     67 |00:00:00.01 |      7 |       |       |   |
    |   3 |   VIEW      |      |     1 |    105 |    105 |00:00:00.01 |     30 |       |       |   |
    |   4 |    TABLE ACCESS FULL| ORDERS |     1 |    105 |    105 |00:00:00.01 |     30 |       |       |   |
    -------------------------------------------------------------------------------------------------------------------
    Predicate Information (identified by operation id):
    ---------------------------------------------------
       1 - access("O"."SALES_REP_ID"="O_VIEW"."SALES_REP_ID")
       2 - filter("O"."ORDER_TOTAL">10000)
    24 rows selected.

    还有其他一些情况,如果出现,也会阻止视图合并的发生,如果一个查询块中包含解析函数或聚合函数,集合运算(UNION,INTERSECT,MINUS),ORDER BY子句或者使用ROWNUM,视图合并将会被禁止或限制。

  4. select e1.last_name,e1.salary,v.avg_salary from employees e1,(select
    department_id,avg(salary)avg_salary from employees e2 group by
    department_id) v where e1.department_id=v.department_id and
    e1.salary>v.avg_salary
    Plan hash value: 2695105989
    -----------------------------------------------------------------------------------------------------------------------
    | Id  | Operation      | Name  | Starts | E-Rows | A-Rows | A-Time  | Buffers |  OMem |  1Mem | Used-Mem |
    -----------------------------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT     |   | 1 |    |  38 |00:00:00.01 | 17 |    |    |       |
    |*  1 |  HASH JOIN      |   | 1 | 17 |  38 |00:00:00.01 | 17 |  1421K|  1421K|  916K (0)|
    |   2 |   VIEW       |   | 1 | 11 |  12 |00:00:00.01 |  7 |    |    |       |
    |   3 |    HASH GROUP BY     |   | 1 | 11 |  12 |00:00:00.01 |  7 |  1106K|  1106K| 1766K (0)|
    |   4 |     TABLE ACCESS FULL| EMPLOYEES | 1 |    107 | 107 |00:00:00.01 |  7 |    |    |       |
    |   5 |   TABLE ACCESS FULL  | EMPLOYEES | 1 |    107 | 107 |00:00:00.01 | 10 |    |    |       |
    -----------------------------------------------------------------------------------------------------------------------
    Predicate Information (identified by operation id):
    ---------------------------------------------------
       1 - access("E1"."DEPARTMENT_ID"="V"."DEPARTMENT_ID")
           filter("E1"."SALARY">"V"."AVG_SALARY")
    Note
    -----
       - this is an adaptive plan

视图合并由以下参数决定:

子查询解嵌套:

子查询解嵌套与视图合并的相似之处在于子查询也是通过一个单独的查询块来表示的,可合并的视图与可以解嵌套的查询之间主要的区别在于他们的位置是不同的。子查询位于where子句,由查询转换器解嵌套的审查。最典型的转换就是讲子查询转变为表联结,如果一个子查询么有解嵌套,将会为它生成一个独立的子计划并作为总的执行计划的一部分按照优化执行速度的次序进行。当子查询不相关的时候,转换查询是非常直接的。

  1. SQL> select * from hr.employees where department_id in (select department_id from hr.departments);
    106 rows selected.
    Execution Plan
    ----------------------------------------------------------
    Plan hash value: 1445457117
    -------------------------------------------------------------------------------
    | Id  | Operation   | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
    -------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT  |       |   106 |  7314 |     3 (0)| 00:00:01 |
    |*  1 |  TABLE ACCESS FULL| EMPLOYEES |   106 |  7314 |     3 (0)| 00:00:01 |

    使用NO_UNNEST提示:

  2. select employee_id,last_name,salary,department_id from employees where
    department_id in(select /*+ no_unnest */ department_id from departments
    where location_id>1700)
    Plan hash value: 4233807898
    ---------------------------------------------------------------------------------------------------------------
    | Id  | Operation       | Name    | Starts | E-Rows | A-Rows |   A-Time   | Buffers | Reads  |
    ---------------------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT      |     |   1 |      |    38 |00:00:00.02 |   32 |     1 |
    |*  1 |  FILTER        |     |   1 |      |    38 |00:00:00.02 |   32 |     1 |
    |   2 |   TABLE ACCESS FULL      | EMPLOYEES   |   1 |  107 |   107 |00:00:00.01 |   10 |     0 |
    |*  3 |   TABLE ACCESS BY INDEX ROWID| DEPARTMENTS |  12 |    1 |     4 |00:00:00.02 |   22 |     1 |
    |*  4 |    INDEX UNIQUE SCAN      | DEPT_ID_PK  |  12 |    1 |    11 |00:00:00.02 |   11 |     1 |
    ---------------------------------------------------------------------------------------------------------------
    Predicate Information (identified by operation id):
    ---------------------------------------------------
       1 - filter( IS NOT NULL)
       3 - filter("LOCATION_ID">1700)
       4 - access("DEPARTMENT_ID"=:B1)
    25 rows selected

select outer.employee_id,outer.last_name,outer.salary,outer.department_i

d from employees outer where outer.salary>(select avg(inner.salary)
from employees inner where inner.department_id=outer.department_id)
    Plan hash value: 2167610409
    -----------------------------------------------------------------------------------------------------------------------
| Id  | Operation      | Name  | Starts | E-Rows | A-Rows | A-Time  | Buffers |  OMem |  1Mem | Used-Mem |
-----------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |   | 1 |    |  38 |00:00:00.01 | 17 |    |    |       |
|*  1 |  HASH JOIN      |   | 1 | 38 |  38 |00:00:00.01 | 17 |  1321K|  1321K| 1067K (0)|
|   2 |   VIEW       | VW_SQ_1  | 1 | 11 |  12 |00:00:00.01 |  7 |    |    |       |
|   3 |    HASH GROUP BY     |   | 1 | 11 |  12 |00:00:00.01 |  7 |  1106K|  1106K|  986K (0)|
|   4 |     TABLE ACCESS FULL| EMPLOYEES | 1 |    107 | 107 |00:00:00.01 |  7 |    |    |       |
|   5 |   TABLE ACCESS FULL  | EMPLOYEES | 1 |    107 | 107 |00:00:00.01 | 10 |    |    |       |
-----------------------------------------------------------------------------------------------------------------------
    Predicate Information (identified by operation id):
---------------------------------------------------
       1 - access("ITEM_1"="OUTER"."DEPARTMENT_ID")
       filter("OUTER"."SALARY">"AVG(INNER.SALARY)")
    Note
-----
   - statistics feedback used for this statement
   - this is an adaptive plan
30 rows selected.

谓词推入:

谓语前推用来将谓语从一个内含查询中应用到不可合并的查询块中。目标就是允许索引的使用或者让其他对于数据集的筛选在查询中能够更早地进行,一般来说,将不需要的数据行尽可能早地过滤都是个好主意,如果一个谓语可以通过将它前推到不可合并查询块中更早的执行,在剩下的执行计划中所需要抓取的数据就会更少,更少的数据意味着要做的事情也更少。

select e1.last_name,e1.salary,v.avg_salary from employees e1,(select
department_id,avg(salary)avg_salary from employees e2 group by
department_id)v where e1.department_id=v.department_id and
e1.salary>v.avg_salary and e1.department_id=60
Plan hash value: 3420982931
--------------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation    | Name      | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
--------------------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |    1 |       |      2 |00:00:00.01 |     6 |       |       |   |
|   1 |  NESTED LOOPS    |      |    1 |     1 |      2 |00:00:00.01 |     6 |       |       |   |
|   2 |   NESTED LOOPS    |      |    1 |       |      5 |00:00:00.01 |     4 |       |       |   |
|   3 |    VIEW     |      |    1 |     5 |      1 |00:00:00.01 |     2 |       |       |   |
|   4 |     HASH GROUP BY   |      |    1 |     5 |      1 |00:00:00.01 |     2 |  1116K|  1116K|  489K (0)|
|   5 |      TABLE ACCESS BY INDEX ROWID BATCHED| EMPLOYEES     |    1 |     5 |      5 |00:00:00.01 |     2 |       |       |   |
|*  6 |       INDEX RANGE SCAN   | EMP_DEPARTMENT_IX |    1 |     5 |      5 |00:00:00.01 |     1 |       |       |   |
|*  7 |    INDEX RANGE SCAN   | EMP_DEPARTMENT_IX |    1 |     5 |      5 |00:00:00.01 |     2 |       |       |   |
|*  8 |   TABLE ACCESS BY INDEX ROWID  | EMPLOYEES     |    5 |     1 |      2 |00:00:00.01 |     2 |       |       |   |
--------------------------------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   6 - access("DEPARTMENT_ID"=60)
   7 - access("E1"."DEPARTMENT_ID"=60)
   8 - filter("E1"."SALARY">"V"."AVG_SALARY")
Note
-----
   - this is an adaptive plan
34 rows selected.

ID=6被推入视图中先执行,

使用rownum禁止谓词推入:

select e1.last_name,e1.salary,v.avg_salary from employees e1,(select
department_id,avg(salary)avg_salary from employees e2 where rownum>1
group by department_id)v where e1.department_id=v.department_id and
e1.salary>v.avg_salary and e1.department_id=60
Plan hash value: 3724319777
------------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation         | Name    | Starts | E-Rows | A-Rows |  A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
------------------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT        |     |  1 |     |    0 |00:00:00.01 |   9 |     |            |
|*  1 |  HASH JOIN         |     |  1 |   3 |    0 |00:00:00.01 |   9 |  1519K|  1519K|  288K (0)|
|   2 |   JOIN FILTER CREATE        | :BF0000    |  1 |   5 |    5 |00:00:00.01 |   2 |     |            |
|   3 |    TABLE ACCESS BY INDEX ROWID BATCHED| EMPLOYEES   |  1 |   5 |    5 |00:00:00.01 |   2 |     |            |
|*  4 |     INDEX RANGE SCAN        | EMP_DEPARTMENT_IX |  1 |   5 |    5 |00:00:00.01 |   1 |     |            |
|*  5 |   VIEW          |     |  1 |  11 |    0 |00:00:00.01 |   7 |     |            |
|   6 |    HASH GROUP BY        |     |  1 |  11 |    0 |00:00:00.01 |   7 |  1484K|  1484K       |
|   7 |     JOIN FILTER USE        | :BF0000    |  1 | 107 |    0 |00:00:00.01 |   7 |     |            |
|   8 |      COUNT         |     |  1 |     |    0 |00:00:00.01 |   7 |     |            |
|*  9 |       FILTER         |     |  1 |     |    0 |00:00:00.01 |   7 |     |            |
|  10 |        TABLE ACCESS FULL       | EMPLOYEES   |  1 | 107 |  107 |00:00:00.01 |   7 |     |            |
------------------------------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - access("E1"."DEPARTMENT_ID"="V"."DEPARTMENT_ID")
       filter("E1"."SALARY">"V"."AVG_SALARY")
   4 - access("E1"."DEPARTMENT_ID"=60)
   5 - filter("V"."DEPARTMENT_ID"=60)
   9 - filter(ROWNUM>1)

34 rows selected.

使用物化视图进行查询重写:

SQL> select p.prod_id,p.prod_name,t.time_id,t.week_ending_day,s.channel_id,s.promo_id,s.cust_id,s.amount_sold from sales s,products p,times t where s.time_id=t.time_id and s.prod_id=p.prod_id;
Execution Plan
----------------------------------------------------------
Plan hash value: 187439137
----------------------------------------------------------------------------------------------------------
| Id  | Operation        | Name  | Rows  | Bytes | Cost (%CPU)| Time  | Pstart| Pstop |
----------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT       |   |   918K|    65M|   542   (3)| 00:00:01 |  |  |
|*  1 |  HASH JOIN        |   |   918K|    65M|   542   (3)| 00:00:01 |  |  |
|   2 |   PART JOIN FILTER CREATE     | :BF0000  |  1826 | 29216 |    18   (0)| 00:00:01 |  |  |
|   3 |    TABLE ACCESS FULL       | TIMES  |  1826 | 29216 |    18   (0)| 00:00:01 |  |  |
|*  4 |   HASH JOIN        |   |   918K|    51M|   522   (2)| 00:00:01 |  |  |
|   5 |    TABLE ACCESS FULL       | PRODUCTS |    72 |  2160 |     3   (0)| 00:00:01 |  |  |
|   6 |    PARTITION RANGE JOIN-FILTER|   |   918K|    25M|   517   (2)| 00:00:01 |:BF0000|:BF0000|
|   7 |     TABLE ACCESS FULL       | SALES  |   918K|    25M|   517   (2)| 00:00:01 |:BF0000|:BF0000|
----------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - access("S"."TIME_ID"="T"."TIME_ID")
   4 - access("S"."PROD_ID"="P"."PROD_ID")
Note
-----
   - this is an adaptive plan
SQL> create materialized view sales_time_product_mv enable query rewrite as select p.prod_id,p.prod_name,t.time_id,t.week_ending_day,s.channel_id,s.promo_id,s.cust_id,s.amount_sold from sales s,products p,times t where s.time_id=t.time_id and s.prod_id=p.prod_id
SQL> select /*+ rewrite(sales_time_product_mv) */p.prod_id,p.prod_name,t.time_id,t.week_ending_day,s.channel_id,s.promo_id,s.cust_id,s.amount_sold from sales s,products p,times t where s.time_id=t.time_id and s.prod_id=p.prod_id;
Execution Plan
----------------------------------------------------------
Plan hash value: 663088863
------------------------------------------------------------------------------------------------------
| Id  | Operation       | Name       | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT      |        |  918K|   52M| 2334   (1)| 00:00:01 |
|   1 |  MAT_VIEW REWRITE ACCESS FULL| SALES_TIME_PRODUCT_MV |  918K|   52M| 2334   (1)| 00:00:01 |
------------------------------------------------------------------------------------------------------
时间: 2024-08-09 06:35:33

查询转换的相关文章

oracle查询转换_inlist转换

oracle的optimizer会对一些sql语句进行查询转换,比如: 合并视图 子查询非嵌套化 inlist转换 下面讲讲遇到的in list转化优化的案例: create table test( col1 varchar2(12) col2 number ext varchar2(4000) ); create index test_ind on test(user_id, col2); create sequence seq_test cache 200; 第一步:准备一些测试数据(10个

oracle查询转换_view merge

oracle对于子查询的支持做的很好,oracle optimizer会对inline view进行query transfomation,即视图合并,不过也经常带来意想不到的问题.下面是一个inline view的merge的例子: 1, 创建临时表 1 create table test1 as select * from dba_objects; 2 create table test2 as select * from dba_objects; 2, 以下查询语句 select * fr

Oracle 查询转换之子查询展开

概念:子查询展开(Subquery Unnesting)是优化器处理带子查询的目标sql的一种优化手段,它是指优化器不再将目标sql中子查询当作一个独立的处理单元来单独执行,而是将该子查询转换为它自身和外部查询之间等价的表连接.这种等价连接转换要么是将子查询展开(即将该子查询中的表,视图从子查询中拿出来,然后和外部查询中的表,视图做表连接),要么是不拆开但是会把该子查询转换为一个内嵌视图(Inline View)然后再和外部查询中的表,视图做表连接.Oracle 会确保子查询展开所对应的等价连接

优化器的查询转换

1.视图合并 SQL> create view emp_vm as 2 select empno,ename,job,sal,comm,deptno 3 from emp 4 where deptno=30; View created. SQL> select empno 2 from emp_vm 3 where empno > 150; EMPNO ---------- 7499 7521 7654 7698 7844 7900 6 rows selected. SQL> se

mysql5.6.16下跟踪SQL查询转换的结果

当SQL执行时,会做一些查询转换,你看到的SQL很可能被转换为其他的形式的SQL执行(有视图重写,查询转换,谓词推进等).在Oracle下,可以通过10053跟踪SQL语句.在mysql下,可以通过设置optimizer_trace来实现. mysql> select version(); +-----------+ | version() | +-----------+ | 5.6.16    | +-----------+ 1 row in set (0.00 sec) mysql> cr

Oracle查询转换之视图合并

一.简单视图合并:指针对那些不含外连接,以及所带视图定义sql语句中不含distinct,group by等聚合函数的目标sql的视图合并. 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'; 视图合并:   SELECT t1.prod_id, t1.prod_nam

Oracle查询转换之连接谓词推入

连接谓词推入(Join Predicate  Pushdown)是优化器处理带视图的目标SQL的一种优化手段,它是指虽然优化器会把该SQL中视图的定义SQL语句当作一个独立单元来单独执行,但此时优化器会把原本处于该视图外部查询中和该视图之间的连接条件推入到该视图的定义SQL语句内部,这样是为了能使用上该视图内部相关基表上的索引,进而能走出基于索引的嵌套循环连接. 连接谓词推入所带来的基于索引的嵌套循环连接并不一定能走出更高效的执行计划,因为当做了连接谓词推入后,原目标SQL中的视图就和外部查询产

一个查询转换

题目:There are two table: T_A (name VARCHAR2(100)) T_B (name VARCHAR2(100), name_a VARCHAR2(100)); The values are: (1) Please write a SQL to output below result: Name         Apple       Orange       Banana -----------  ----------  -----------  -------

网络地址转换NAT

一.网络地址转换NAT: 在专用网内部的一些主机本来已经分配到了本地IP地址,但现在想和Internet上的主机进行通信,最简单的办法就是再申请一些全球的IP地址,但是全球的IPv4的地址已经不多了,所以采用了一种方法是网络地址转换. 在专用网连接到Internet的路由器上安装NAT软件,把装有NAT软件的路由器叫做NAT路由器,它至少有一个有效的外部全球IP地址,才能和Internet连接.所有使用本地地址的主机和Internet进行通信时,都要在NAT路由器上经本地地址转换成全球的IP地址