MERGE提示的作用和使用方法
MERGE提示是指导优化器,合并查询中的视图。出现在from子句中的子查询,也被视为视图。
MERGE提示的使用语法如下图所示:
其中:
tablespec表示目标表的名称或别名(当有别名时,必须用别名)。但不要加入表的属主(SCHEMA)名,哪怕在SQL中,明确写了属主,提示中也不能写。
queryblock表示查询块。优化器在为一条SQL制定执行计划时,会将该SQL中涉及的子查询和视图,拆分为相应的查询块。分别为每一个查询块制定执计划。
这里需要注意的是,当MERGE后面不带参数时,需要把MERGE写到视图所在的查询块内,而带参数时,则要写到外层的查询中。
其使用方法和注意事项,也与INDEX提示相同,为节省篇幅,这再不再赘述。
下面,我们通过实验来说明施加该提示时,优化器是如何来合并视图的。
测试验证
首先,我们创建两张测试表TESTTAB和TABLIST,并分别收集统计信息:
设置SQLPLUS下的环境参数,以便显示的内容方便查看。如下图所示:
发出以下查询:
select t1.owner,t1.object_name,t1.object_id
from testtab t1,
(select owner,max(table_name) max_name
from tablist
group by owner) t2
where t1.owner=t2.owner
and t1.object_name=t2.max_name
and t1.object_type like 'TABLE%';
在该查询中,别名为t2的子查询,出现在了外层查询的from子句中,其亦被视为视图。当我们什么提示都不加时,Oracle优化器给出的执行计划如下所示:
如上图所示,我们可以看到子查询t2并没有被“合并”,而是先进行处理,其处理后的结果,再与t1表做关联。
而当我们添加merger提示后,如下所示:
select /*+ merge(t2) */ t1.owner,t1.object_name,t1.object_id
from testtab t1,
(select owner,max(table_name) max_name
from tablist
group by owner) t2
where t1.owner=t2.owner
and t1.object_name=t2.max_name
and t1.object_type like 'TABLE%';
这里请注意,由于该merge提示是在主查询上添加的,所以,需要带上参数,指定对t2表示的视图进行合并。其执行计划如下图所示:
如上图所示,我们可以看到tablist表是先与主查询中的testtab表做关联,关联后的结果再做的GROUP BY处理。
如前所述,当我们把merger提示写到视图所在的查询块内时,不需要加参数,如下所示:
select t1.owner,t1.object_name,t1.object_id
from testtab t1,
(select /*+ merge */ owner,max(table_name) max_name
from tablist
group by owner) t2
where t1.owner=t2.owner
and t1.object_name=t2.max_name
and t1.object_type like 'TABLE%';
此时的执行计划与上一SQL的执行计划是相同的。
当视图单独处理时,可以产生较少的中间结果时,不合并通常效率会更高,反之,如果视图内的表先与外层查询中的表关联后,能大幅减少中间结果,则合并通常会效率更高。
知识总结
1、MERGE提示是指导优化器,合并查询中的视图。出现在from子句中的子查询,也被视为视图。
2、当MERGE后面不带参数时,需要把MERGE写到视图所在的查询块内,而带参数时,则要写到外层的查询中。
参考文档
《Oracle® Database SQL Language Reference》
标签:name,Hint,t2,owner,t1,MERGE,视图,Oracle,查询 From: https://blog.51cto.com/u_13482808/8525351