oracle 查询改写
阅读目录
- oracle里的查询转换的作用
- 4.2 子查询展开
- 4.3 视图合并
- 4.3.1 简单视图合并
- 4.3.2 外连接视图合并
- 4.3.3 复杂视图合并
- 4.4 星型转换
- 4.5 连接谓词推入
- 4.6 连接因式分解
- 4.7 表扩展
- 4.8 表移除
- 4.9 Oralce如何处理SQL语句中的IN
- 4.9.1 IN-List Iterator
- 4.9.2 IN-List Expansion/OR Expansion
- 4.9.3 IN-List Filter
- 4.9.4 对IN做子查询展开/视图合并
情形2:
先将子查询转换为内嵌视图,然后和外部查询中的表、视图做表连接:
View Code
oracle对包含视图的目标SQL做简单视图合并也是有前提条件的,该SQL所包含视图的视图定义SQL语句中一定不能出现如下内容(包括但不限于):
- 集合运算符(UNION,UNION ALL, INITERSECT,MINUS)
- CONNECT BY 子句
- ROWNUM
- .......
不能做视图合并的例子:
create or replace view SH.view_1_union as
select T2.PROD_ID
from sh.SALES t2
join sh.CUSTOMERS t3 on t2.CUST_ID=t3.CUST_ID
where t3.CUST_GENDER='MALE'
union all
select PROD_ID
from sh.sales t2
where t2.amount_sold1000;
View Code
4.3.2 外连接视图合并
外连接视图合并是指针对那些使用了外连接,以及所带视图的视图定义SQL语句中不包含distinct、group by等聚合函数的目标SQL的视图合并。这里“使用外连接”的含义是指外部查询的表和视图之间使用了外连接,或者该视图的视图定义SQL语句中使用了外连接。
关于外连接视图合并有一个很常用的限制,即当目标视图在和外部查询的表做外连接时,该目标视图可以做外连接视图合并的前提条件是,
- 要么该视图被作为外连接的驱动表,
- 要么该视图虽然被作为外连接的被驱动表但它的视图定义SQL语句中只包含一个表。
4.3.3 复杂视图合并
指针对那些所带视图的视图定义SQL语句中含有group by或distinct的目标SQL的视图合并。
意味着把其定义SQL语句拆开,并把其中的基表拿出来和外部查询中的表合并。这通常意味着上述视图定义SQL语句中的group by或distinct操作会被推迟执行,也就是说,这种情况下通常会先做表连接,再做group by或distinct操作,而不是像未做复杂视图合并时那样先在视图内部做完group by或distinct操作,然后才和外部查询中的表做表连接。
例子:
create view view_3 as select CUST_ID,PROD_ID,sum(QUANTITY_SOLD) as total from sh.sales group by CUST_ID,PROD_ID;;
select /+merge(t3)/t1.CUST_ID,t1.CUST_LAST_NAME
from sh.CUSTOMERS t1
join view_3 t3 on t1.CUST_ID=t3.CUST_ID
join sh.PRODUCTS t2 on t2.PROD_ID=t3.CUST_ID
where t3.TOTAL>700
and t2.PROD_CATEGORY='Hardware'
and t1.CUST_YEAR_OF_BIRTH=1977
and t1.CUST_MARITAL_STATUS='married';
View Code
下面是没做视图合并

回到顶部
4.4 星型转换
它的核心是将原星型连接中针对各个维度表的限制条件,通过等价改写的方式以额外的子查询施加到事实表上,然后通过对事实表上各连接列上已存在的位图索引间的位图操作(如按位与、按位或等),来达到有效减少事实表上待访问的数据量,避免对事实表做全表扫描的目的,这就可以有效缩短原SQL的执行时间,提高其执行效率。
例子:
123456 | select /*cs1*/
t2.CUST_CITY,
sum
(t1.AMOUNT_SOLD)
as AMOUNT_SOLD_total
from sh.SALES t1 ,sh.CUSTOMERS t2,sh.PRODUCTS t3,sh.CHANNELS t4
where
t1.CUST_ID=t2.CUST_ID
and t1.PROD_ID=t3.PROD_ID
and
t1.CHANNEL_ID=t4.CHANNEL_ID
and t2.COUNTRY_ID=52771
and
t3.PROD_NAME=
'Mouse Pad' and t4.CHANNEL_DESC=
'Internet' group by
t2.CUST_CITY |