更新时间:2024-11-05 GMT+08:00

指定子查询不提升的hint

功能描述

优化器在对查询进行逻辑优化时通常会将可以提升的子查询提升到上层以避免嵌套执行,但对于某些场景,嵌套执行不会导致性能下降过多,而提升之后扩大了查询路径的搜索范围,可能导致性能变差。对于此类情况,可以使用no merge hint指定子查询不提升进行调试。大多数情况下不建议使用此hint。

语法格式

1
no merge [(subquery_name)]

参数说明

subquery_name为目标子查询名,亦可以是view或cte名,表示该子查询在逻辑优化时不会进行提升;当不指定subquery_name时,表示当前查询不提升。

示例

创建表t1、t2、t3:

1
2
3
create table t1(a1 int,b1 int,c1 int,d1 int);
create table t2(a2 int,b2 int,c2 int,d2 int);
create table t3(a3 int,b3 int,c3 int,d3 int);

原语句为:

1
explain select * from t3, (select a1,b2,c1,d2 from t1,t2 where t1.a1=t2.a2) s1 where t3.b3=s1.b2;

上述查询中,可以使用以下两种方式禁止子查询s1进行提升:

  • 方式一:
    1
    explain select /*+ no merge(s1) */ * from t3, (select a1,b2,c1,d2 from t1,t2 where t1.a1=t2.a2) s1 where t3.b3=s1.b2;
    
  • 方式二:
    1
    explain select * from t3, (select /*+ no merge */ a1,b2,c1,d2 from t1,t2 where t1.a1=t2.a2) s1 where t3.b3=s1.b2;
    

提升后效果: