oracle的cte,oracle CTE 简介 | 学步园

oracle 9i r2中引入了SQL-99中的with子句,它是一个实现子查询的工具,

我们可以用它来临时存储oracle经过计算得到的结果集。

with子句的作用有点类似global temporary tables,设计with子句目的,

是为提高复杂子查询的速度。下面是with子句的一些要点:

1.with子句应用于oracle 9i以及更高版本

2.正式的,with子句称作分解子查询

3.with子句应用于当一个查询被多次执行的情况

4.with子句对于递归查询也很有用(SQL-99,oracle不支持)

为了简单起见,下面的例子仅仅引用集合一次;

而with子句通常被用在一个查询中多次引用一个集合情况下。

--

with子句能够简化复杂的sql查询

在SQL-99中,我们可以用with子句来代替临时表。

oracle中的with子句一次性获得一个集合,并为其取一个名,

以便于我们在后面的查询中引用到它。

--

首先,SQL-99中的with子句让人很困惑,因为这个sql语句不是以select开始的;

然而,我们的查询语句可以以with子句开始,定义一个集合,在主查询中引用到集合,

它就好像一个"真正的表":

with subquery_name

as (

the aggregation SQL statement)

select (

query naming subquery_name);

--

回到我们过于简单化的例子,我们用with子句代替临时表(注意:通过使用global temporary table,

你会发现你的执行计划更优了,不过这取决于你的oracle版本):

WITH sum_sales AS(

select /*+ materialize */

sum(quantity) all_sales

from stores ),

number_stores AS(

select /*+ materialize */

count(*) nbr_stores

from stores ),

sales_by_store AS(

select /*+ materialize */

store_name,

sum(quantity) store_sales

from

store natural join sales )

SELECT store_name

FROM

store,

sum_sales,

number_stores,

sales_by_store

where

store_sales > (all_sales / nbr_stores);

--

注释掉了oracle中没有公开的实现提示;oracle中的实现提示是用来确定

在with子句内部创建的临时表是基于开销优化的。对于oracle 10g版本来说,

这是不必要的,但是它确保了这个表只被创建一次。

应该指出的是,with子句在oracle中并不是完全的起作用,

oracle的sql中就不支持用with来替代connect by的递归查询。

--

Here is an actual performance comparison of equivalent queries:

SQL> --*********************************************

SQL> -- Using subqueries

SQL> --*********************************************

SQL>

SQL> select

2 store_name,

3 sum(quantity) store_sales,

4 (select sum(quantity) from sales)/(select count(*) from store) avg_sales

5 from

6 store s,

7 sales sl

8 where

9 s.store_key = sl.store_key

10 having

11 sum(quantity) > (select sum(quantity) from sales)/(select count(*) from store)

12 group by

13 store_name

14 ;

----------------------------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

----------------------------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 1 | 31 | 4 (25)| 00:00:01 |

| 1 | SORT AGGREGATE | | 1 | 4 | | |

| 2 | TABLE ACCESS FULL | SALES | 100 | 400 | 2 (0)| 00:00:01 |

| 3 | SORT AGGREGATE | | 1 | | | |

| 4 | INDEX FULL SCAN | SYS_C003999 | 10 | | 1 (0)| 00:00:01 |

|* 5 | FILTER | | | | | |

| 6 | HASH GROUP BY | | 1 | 31 | 4 (25)| 00:00:01 |

| 7 | NESTED LOOPS | | 100 | 3100 | 3 (0)| 00:00:01 |

| 8 | TABLE ACCESS FULL | SALES | 100 | 900 | 2 (0)| 00:00:01 |

| 9 | TABLE ACCESS BY INDEX ROWID| STORE | 1 | 22 | 1 (0)| 00:00:01 |

|* 10 | INDEX UNIQUE SCAN | SYS_C003999 | 1 | | 0 (0)| 00:00:01 |

| 11 | SORT AGGREGATE | | 1 | 4 | | |

| 12 | TABLE ACCESS FULL | SALES | 100 | 400 | 2 (0)| 00:00:01 |

| 13 | SORT AGGREGATE | | 1 | | | |

| 14 | INDEX FULL SCAN | SYS_C003999 | 10 | | 1 (0)| 00:00:01 |

----------------------------------------------------------------------------------------------

113 consistent gets //IO数量

--

SQL> --*********************************************

SQL> -- Using CTAS(create table as select)

SQL> --*********************************************

SQL> create table t1 as select sum(quantity) all_sales from sales;

Table created.

SQL> create table t2 as select count(*) nbr_stores from store;

Table created.

SQL> create table t3 as select store_name, sum(quantity) store_sales from store natural join sales group by store_name;

Table created.

SQL>

SQL> select

2 store_name

3 from

4 t1,

5 t2,

6 t3

7 where

8 store_sales > (all_sales / nbr_stores);

------------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

------------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 1 | 61 | 6 (0)| 00:00:01 |

| 1 | NESTED LOOPS | | 1 | 61 | 6 (0)| 00:00:01 |

| 2 | MERGE JOIN CARTESIAN| | 1 | 26 | 4 (0)| 00:00:01 |

| 3 | TABLE ACCESS FULL | T1 | 1 | 13 | 2 (0)| 00:00:01 |

| 4 | BUFFER SORT | | 1 | 13 | 2 (0)| 00:00:01 |

| 5 | TABLE ACCESS FULL | T2 | 1 | 13 | 2 (0)| 00:00:01 |

|* 6 | TABLE ACCESS FULL | T3 | 1 | 35 | 2 (0)| 00:00:01 |

------------------------------------------------------------------------------

30 consistent gets

--

SQL> --*********************************************

SQL> -- Using the WITH clause

SQL> --*********************************************

SQL>

SQL> with

2 number_stores as

3 (select count(*) nbr_stores from store),

4 total_sales as

5 (select sum(quantity) all_sales from sales),

6 store_sales as

7 (select store_name, sum(quantity) sales from store natural join sales group by store_name)

8 select

9 store_name

10 from

11 number_stores,

12 total_sales,

13 store_sales

14 where

15 sales > (all_sales / nbr_stores);

-----------------------------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

-----------------------------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 1 | 61 | 7 (15)| 00:00:01 |

| 1 | NESTED LOOPS | | 1 | 61 | 7 (15)| 00:00:01 |

| 2 | NESTED LOOPS | | 1 | 26 | 3 (0)| 00:00:01 |

| 3 | VIEW | | 1 | 13 | 1 (0)| 00:00:01 |

| 4 | SORT AGGREGATE | | 1 | | | |

| 5 | INDEX FULL SCAN | SYS_C003999 | 10 | | 1 (0)| 00:00:01 |

| 6 | VIEW | | 1 | 13 | 2 (0)| 00:00:01 |

| 7 | SORT AGGREGATE | | 1 | 4 | | |

| 8 | TABLE ACCESS FULL | SALES | 100 | 400 | 2 (0)| 00:00:01 |

|* 9 | VIEW | | 1 | 35 | 4 (25)| 00:00:01 |

| 10 | SORT GROUP BY | | 10 | 310 | 4 (25)| 00:00:01 |

| 11 | NESTED LOOPS | | 100 | 3100 | 3 (0)| 00:00:01 |

| 12 | TABLE ACCESS FULL | SALES | 100 | 900 | 2 (0)| 00:00:01 |

| 13 | TABLE ACCESS BY INDEX ROWID| STORE | 1 | 22 | 1 (0)| 00:00:01 |

|* 14 | INDEX UNIQUE SCAN | SYS_C003999 | 1 | | 0 (0)| 00:00:01 |

-----------------------------------------------------------------------------------------------

109 consistent gets

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值