VIEW_FILTER_MERGING
指定是否对视图条件进行优化以及如何优化。
参数解析
属性:会话级(支持 HINT 指定) 缺省值:138
VIEW_FILTER_MERGING 取不同值的效果如下:
- 0:不进行视图合并;
- 1:尽可能地进行视图合并;
- 2:自动判断是否进行视图合并,以下两种条件则不进行视图合并:
- 视图在查询中出现次数多次且不是简单视图;
- 视图中包含过多的集合运算(>= 10),或待合并的过滤条件为复杂布尔表达式;
- 4:视图包含分析函数时,如果分析函数的
partition by具有唯一性,则外层过滤条件会下推到视图内部; - 8:如果派生表存在集函数,则不进行条件下推优化;
- 16:收集公用表达式相关的所有过滤条件,改写合并所有条件,并下放到公用表达式的内部;
- 32:
TOP信息下推到派生表; - 64:外层布尔表达式隐式声明
IS NOT NULL属性,对派生表/视图对应的列显示添加COL IS NOT NULL布尔表达式; - 128:外层
ROWNUM过滤表达式尝试下放至视图/派生表生成TOP子句; - 256:当满足以下条件时,对相关派生表过滤条件进行下推优化:
- 过滤条件对应派生表的查询项,并且是查询表达式;
- 过滤条件列映射为查询表达式的引用列,并且引用列来自派生表的
FROM项;
- 512:视图已经有过滤条件的,不重复下放,为了后续能使用
htab; - 1024:包含该值时,取消下述限制:
- 视图是集合运算时的分支数应小于 10;
- 若视图是集合运算且超过 2 个分支时,过滤条件不能含有复杂函数/表达式;
其实这个效果的表述问题有点多,有以下问题,这些问题都需要测试:
- 当取值为 2 的时候,视图在查询中出现多少次才不会合并;
- 当取值为 2 的时候,简单视图需要多简单才不会合并;
- 当取值为 16 的时候,公用表达式是什么;
- 当取值为 64 的时候,如何隐式声明
IS NOT NULL属性; - 当取值为 256 的时候,查询项可以为标量子查询/case when 这种查询项吗;
- 和 [[complex-view-merging]] 有什么区别;
原理解析
构造以下 SQL
CREATE TABLE TEST_LG1 ( A1 INT, B1 VARCHAR(255) );
CREATE TABLE TEST_LG2 ( A2 INT, B2 VARCHAR(255) );
CREATE TABLE TEST_LG3 ( A3 INT, B3 VARCHAR(255) );
CREATE TABLE TEST_LG4 ( A4 INT, B4 VARCHAR(255) );
INSERT INTO TEST_LG1 SELECT LEVEL,LEVEL FROM DUAL CONNECT BY LEVEL <= 100000;
INSERT INTO TEST_LG2 SELECT LEVEL,LEVEL FROM DUAL CONNECT BY LEVEL <= 100000;
INSERT INTO TEST_LG3 SELECT LEVEL,LEVEL FROM DUAL CONNECT BY LEVEL <= 100000;
INSERT INTO TEST_LG4 SELECT LEVEL,LEVEL FROM DUAL CONNECT BY LEVEL <= 100000;
CREATE OR REPLACE VIEW V_TEST_LG(A,B) AS
SELECT A1,B1 FROM TEST_LG1 WHERE A1 = 1
UNION
SELECT A2,B2 FROM TEST_LG2 WHERE A2 = 1 AND B2 = 2
UNION
SELECT A3,B3 FROM TEST_LG3 WHERE A3 > 5
UNION
SELECT A4,B4 FROM TEST_LG4 WHERE B4 < 5;
值为 0
不进行视图合并。
此时查看以下 SQL 的执行计划
EXPLAIN SELECT /*+VIEW_FILTER_MERGING(0) COMPLEX_VIEW_MERGING(0)*/ * FROM V_TEST_LG WHERE A = 1;
1 #NSET2: [56, 3, 52]
2 #PRJT2: [56, 3, 52]; exp_num(2), is_atom(FALSE)
3 #SLCT2: [56, 3, 52]; V_TEST_LG.A = 1
4 #PRJT2: [56, 126, 52]; exp_num(2), is_atom(FALSE)
5 #DISTINCT: [56, 126, 52]
6 #UNION ALL: [55, 12625, 52]
7 #PRJT2: [40, 7625, 52]; exp_num(2), is_atom(FALSE)
8 #UNION ALL: [40, 7625, 52]
9 #PRJT2: [26, 2625, 52]; exp_num(2), is_atom(FALSE)
10 #UNION ALL: [26, 2625, 52]
11 #PRJT2: [12, 2500, 52]; exp_num(2), is_atom(FALSE)
12 #SLCT2: [12, 2500, 52]; TEST_LG1.A1 = 1
13 #CSCN2: [12, 100000, 52]; INDEX33555467(TEST_LG1); btr_scan(1)
14 #PRJT2: [12, 125, 52]; exp_num(2), is_atom(FALSE)
15 #SLCT2: [12, 125, 52]; (TEST_LG2.A2 = 1 AND exp_cast(TEST_LG2.B2) = 2)
16 #CSCN2: [12, 100000, 52]; INDEX33555468(TEST_LG2); btr_scan(1)
17 #PRJT2: [12, 5000, 52]; exp_num(2), is_atom(FALSE)
18 #SLCT2: [12, 5000, 52]; TEST_LG3.A3 > 5
19 #CSCN2: [12, 100000, 52]; INDEX33555469(TEST_LG3); btr_scan(1)
20 #PRJT2: [12, 5000, 52]; exp_num(2), is_atom(FALSE)
21 #SLCT2: [12, 5000, 52]; exp_cast(TEST_LG4.B4) < 5
22 #CSCN2: [12, 100000, 52]; INDEX33555470(TEST_LG4); btr_scan(1)
此时 SLCT2 并没有下放到视图内,执行计划也就是正常的情况,先把 select * from v_test_lg 查询出来,然后再进行过滤。
值为 1
尽可能地进行视图合并。
此时继续查看以下 SQL 的执行计划
EXPLAIN SELECT /*+VIEW_FILTER_MERGING(1) COMPLEX_VIEW_MERGING(0)*/ * FROM V_TEST_LG WHERE A = 1;
1 #NSET2: [41, 27, 52]
2 #PRJT2: [41, 27, 52]; exp_num(2), is_atom(FALSE)
3 #PRJT2: [41, 27, 52]; exp_num(2), is_atom(FALSE)
4 #DISTINCT: [41, 27, 52]
5 #UNION ALL: [40, 2750, 52]
6 #PRJT2: [26, 2625, 52]; exp_num(2), is_atom(FALSE)
7 #PRJT2: [26, 2625, 52]; exp_num(2), is_atom(FALSE)
8 #UNION ALL: [26, 2625, 52]
9 #PRJT2: [12, 2500, 52]; exp_num(2), is_atom(FALSE)
10 #SLCT2: [12, 2500, 52]; TEST_LG1.A1 = 1
11 #CSCN2: [12, 100000, 52]; INDEX33555467(TEST_LG1); btr_scan(1)
12 #PRJT2: [12, 125, 52]; exp_num(2), is_atom(FALSE)
13 #SLCT2: [12, 125, 52]; (TEST_LG2.A2 = 1 AND exp_cast(TEST_LG2.B2) = 2)
14 #CSCN2: [12, 100000, 52]; INDEX33555468(TEST_LG2); btr_scan(1)
15 #PRJT2: [12, 125, 52]; exp_num(2), is_atom(FALSE)
16 #SLCT2: [12, 125, 52]; (TEST_LG4.A4 = 1 AND exp_cast(TEST_LG4.B4) < 5)
17 #CSCN2: [12, 100000, 52]; INDEX33555470(TEST_LG4); btr_scan(1)
这个时候会把 where a = 1 下推到视图中每一个查询里。
可以看到少了对 TEST_LG3 表的查询,这是因为 TEST_LG3 的查询项 A3 > 5 AND A3 = 1 必定为 false,所以直接把 TEST_LG3 裁剪了。
值为 2
自动判断是否进行视图合并,以下两种条件则不进行视图合并:
- 视图在查询中出现次数多次且不是简单视图;
- 视图中包含过多的集合运算(>= 10),或待合并的过滤条件为复杂布尔表达式;
以下是不进行视图合并的情况
- 视图被查询多次的时候,无法进行视图合并
select
/*+view_filter_merging(2) complex_view_merging(0)*/
*
from
(
select * from v_test_lg
union all
select * from v_test_lg
) t
where
t.a = 1;
此时的执行计划为
1 #NSET2: [111, 55, 52]
2 #PRJT2: [111, 55, 52]; exp_num(2), is_atom(FALSE)
3 #PRJT2: [111, 55, 52]; exp_num(2), is_atom(FALSE)
4 #UNION ALL: [111, 55, 52]
5 #PRJT2: [55, 27, 52]; exp_num(2), is_atom(FALSE)
6 #PRJT2: [55, 27, 52]; exp_num(2), is_atom(FALSE)
7 #DISTINCT: [55, 27, 52]
8 #UNION ALL: [54, 2751, 52]
9 #PRJT2: [40, 2626, 52]; exp_num(2), is_atom(FALSE)
10 #UNION ALL: [40, 2626, 52]
11 #PRJT2: [26, 2625, 52]; exp_num(2), is_atom(FALSE)
12 #UNION ALL: [26, 2625, 52]
13 #PRJT2: [12, 2500, 52]; exp_num(2), is_atom(FALSE)
14 #SLCT2: [12, 2500, 52]; TEST_LG1.A1 = 1
15 #CSCN2: [12, 100000, 52]; INDEX33555467(TEST_LG1); btr_scan(1)
16 #PRJT2: [12, 125, 52]; exp_num(2), is_atom(FALSE)
17 #SLCT2: [12, 125, 52]; (TEST_LG2.A2 = 1 AND exp_cast(TEST_LG2.B2) = 2)
18 #CSCN2: [12, 100000, 52]; INDEX33555468(TEST_LG2); btr_scan(1)
19 #PRJT2: [12, 1, 52]; exp_num(2), is_atom(FALSE)
20 #SLCT2: [12, 1, 52]; 1 > 5
21 #CSCN2: [12, 100000, 52]; INDEX33555469(TEST_LG3); btr_scan(1)
22 #PRJT2: [12, 125, 52]; exp_num(2), is_atom(FALSE)
23 #SLCT2: [12, 125, 52]; (exp_cast(TEST_LG4.B4) < 5 AND TEST_LG4.A4 = 1)
24 #CSCN2: [12, 100000, 52]; INDEX33555470(TEST_LG4); btr_scan(1)
25 #PRJT2: [55, 27, 52]; exp_num(2), is_atom(FALSE)
26 #PRJT2: [55, 27, 52]; exp_num(2), is_atom(FALSE)
27 #DISTINCT: [55, 27, 52]
28 #UNION ALL: [54, 2751, 52]
29 #PRJT2: [40, 2626, 52]; exp_num(2), is_atom(FALSE)
30 #UNION ALL: [40, 2626, 52]
31 #PRJT2: [26, 2625, 52]; exp_num(2), is_atom(FALSE)
32 #UNION ALL: [26, 2625, 52]
33 #PRJT2: [12, 2500, 52]; exp_num(2), is_atom(FALSE)
34 #SLCT2: [12, 2500, 52]; TEST_LG1.A1 = 1
35 #CSCN2: [12, 100000, 52]; INDEX33555467(TEST_LG1); btr_scan(1)
36 #PRJT2: [12, 125, 52]; exp_num(2), is_atom(FALSE)
37 #SLCT2: [12, 125, 52]; (TEST_LG2.A2 = 1 AND exp_cast(TEST_LG2.B2) = 2)
38 #CSCN2: [12, 100000, 52]; INDEX33555468(TEST_LG2); btr_scan(1)
39 #PRJT2: [12, 1, 52]; exp_num(2), is_atom(FALSE)
40 #SLCT2: [12, 1, 52]; 1 > 5
41 #CSCN2: [12, 100000, 52]; INDEX33555469(TEST_LG3); btr_scan(1)
42 #PRJT2: [12, 125, 52]; exp_num(2), is_atom(FALSE)
43 #SLCT2: [12, 125, 52]; (exp_cast(TEST_LG4.B4) < 5 AND TEST_LG4.A4 = 1)
44 #CSCN2: [12, 100000, 52]; INDEX33555470(TEST_LG4); btr_scan(1)
可以看到 TEST_LG3 是没有被裁剪的,再看此 SQL 的执行计划
select
/*+view_filter_merging(2) complex_view_merging(0)*/
*
from
( select * from v_test_lg ) t
where
t.a = 1;
1 #NSET2: [41, 27, 52]
2 #PRJT2: [41, 27, 52]; exp_num(2), is_atom(FALSE)
3 #PRJT2: [41, 27, 52]; exp_num(2), is_atom(FALSE)
4 #DISTINCT: [41, 27, 52]
5 #UNION ALL: [40, 2750, 52]
6 #PRJT2: [26, 2625, 52]; exp_num(2), is_atom(FALSE)
7 #PRJT2: [26, 2625, 52]; exp_num(2), is_atom(FALSE)
8 #UNION ALL: [26, 2625, 52]
9 #PRJT2: [12, 2500, 52]; exp_num(2), is_atom(FALSE)
10 #SLCT2: [12, 2500, 52]; TEST_LG1.A1 = 1
11 #CSCN2: [12, 100000, 52]; INDEX33555467(TEST_LG1); btr_scan(1)
12 #PRJT2: [12, 125, 52]; exp_num(2), is_atom(FALSE)
13 #SLCT2: [12, 125, 52]; (TEST_LG2.A2 = 1 AND exp_cast(TEST_LG2.B2) = 2)
14 #CSCN2: [12, 100000, 52]; INDEX33555468(TEST_LG2); btr_scan(1)
15 #PRJT2: [12, 125, 52]; exp_num(2), is_atom(FALSE)
16 #SLCT2: [12, 125, 52]; (TEST_LG4.A4 = 1 AND exp_cast(TEST_LG4.B4) < 5)
17 #CSCN2: [12, 100000, 52]; INDEX33555470(TEST_LG4); btr_scan(1)
此时 TEST_LG3 是被裁剪的。
可以说明,如果 V_TEST_LG 被查询多次之后,没有办法进行视图合并。
- 过滤条件为复杂表达式时,无法合并视图
查看以下 SQL 的执行计划
select
/*+view_filter_merging(2) complex_view_merging(0)*/
*
from
(
select
*
from
v_test_lg
) t
where
t.a || '1' || t.b = '111';
1 #NSET2: [54, 3, 52]
2 #PRJT2: [54, 3, 52]; exp_num(2), is_atom(FALSE)
3 #PRJT2: [54, 3, 52]; exp_num(2), is_atom(FALSE)
4 #DISTINCT: [54, 3, 52]
5 #UNION ALL: [53, 315, 52]
6 #PRJT2: [39, 190, 52]; exp_num(2), is_atom(FALSE)
7 #UNION ALL: [39, 190, 52]
8 #PRJT2: [26, 65, 52]; exp_num(2), is_atom(FALSE)
9 #UNION ALL: [26, 65, 52]
10 #PRJT2: [12, 62, 52]; exp_num(2), is_atom(FALSE)
11 #SLCT2: [12, 62, 52]; (TEST_LG1.A1 = 1 AND var3 || TEST_LG1.B1 = '111')
12 #CSCN2: [12, 100000, 52]; INDEX33555467(TEST_LG1); btr_scan(1)
13 #PRJT2: [12, 3, 52]; exp_num(2), is_atom(FALSE)
14 #SLCT2: [12, 3, 52]; (TEST_LG2.A2 = 1 AND var6 || TEST_LG2.B2 = '111' AND exp_cast(TEST_LG2.B2) = 2)
15 #CSCN2: [12, 100000, 52]; INDEX33555468(TEST_LG2); btr_scan(1)
16 #PRJT2: [12, 125, 52]; exp_num(2), is_atom(FALSE)
17 #SLCT2: [12, 125, 52]; (TEST_LG3.A3 > 5 AND exp_cast(exp_cast(TEST_LG3.A3) || '1') || TEST_LG3.B3 = '111')
18 #CSCN2: [12, 100000, 52]; INDEX33555469(TEST_LG3); btr_scan(1)
19 #PRJT2: [12, 125, 52]; exp_num(2), is_atom(FALSE)
20 #SLCT2: [12, 125, 52]; (exp_cast(TEST_LG4.B4) < 5 AND exp_cast(exp_cast(TEST_LG4.A4) || '1') || TEST_LG4.B4 = '111')
21 #CSCN2: [12, 100000, 52]; INDEX33555470(TEST_LG4); btr_scan(1)
此时 TEST_LG3 也没有进行裁剪。
值为 4
视图包含分析函数时,如果分析函数的 partition by 具有唯一性,则外层过滤条件会下推到视图内部。
为了确保分析函数的 partition by 具有唯一性,给 test_lg1 建立一条唯一索引
create unique index idx_test_lg1_a1 on test_lg1(a1);
再看一下这条 SQL 的执行计划
select
*
from
(
select
b1,
row_number() over (
partition by a1
order by
b1
) aa
from
test_lg1
where
b1 < '10'
)
where
b1 > '1';
view_filter_merging = 4 的执行计划为
1 #NSET2: [12, 3750, 64]
2 #PRJT2: [12, 3750, 64]; exp_num(3), is_atom(FALSE)
3 #PRJT2: [12, 3750, 64]; exp_num(3), is_atom(FALSE)
4 #AFUN: [12, 3750, 64]; afun_num(1); partition_num(1)[TEST_LG1.A1]; order_num(1)[TEST_LG1.B1]
5 #SORT3: [12, 3750, 64]; key_num(2), partition_key_num(0), is_distinct(FALSE), top_flag(0), is_adaptive(0)
6 #SLCT2: [12, 3750, 64]; (TEST_LG1.B1 < '10' AND TEST_LG1.B1 > '1')
7 #CSCN2: [12, 100000, 64]; INDEX33555467(TEST_LG1); btr_scan(1)
view_filter_merging = 0 的执行计划为
1 #NSET2: [13, 250, 64]
2 #PRJT2: [13, 250, 64]; exp_num(3), is_atom(FALSE)
3 #SLCT2: [13, 250, 64]; DMTEMPVIEW_889193519.B1 > '1'
4 #PRJT2: [12, 5000, 64]; exp_num(3), is_atom(FALSE)
5 #AFUN: [12, 5000, 64]; afun_num(1); partition_num(1)[TEST_LG1.A1]; order_num(1)[TEST_LG1.B1]
6 #SORT3: [12, 5000, 64]; key_num(2), partition_key_num(0), is_distinct(FALSE), top_flag(0), is_adaptive(0)
7 #SLCT2: [12, 5000, 64]; TEST_LG1.B1 < '10'
8 #CSCN2: [12, 100000, 64]; INDEX33555467(TEST_LG1); btr_scan(1)
其实可以看到,view_filter_merging = 0 的执行计划多了一个 SLCT2 操作符,所以说,当 view_filter_merging = 4 的时候,条件是可以下推的,以此来减少数据页扫描的数量。
值为 8
如果派生表存在集函数,则不进行条件下推优化。
查看以下 SQL 的执行计划
select * from ( select max(c1),1 x from t1 ) t where x > 5;
view_filter_merging(0) 的执行计划为
1 #NSET2: [1, 1, 4]
2 #PRJT2: [1, 1, 4]; exp_num(2), is_atom(FALSE)
3 #PRJT2: [1, 1, 4]; exp_num(2), is_atom(FALSE)
4 #AAGR2: [1, 1, 4]; grp_num(0), sfun_num(1), distinct_flag[0]; slave_empty(0)
5 #SLCT2: [1, 1, 4]; FALSE
6 #CSCN2: [1, 1, 4]; INDEX33555472(T1); btr_scan(1)
此时的 SLCT2 操作符很明显下推到了派生表中,他在 PRJT2 操作符下面。
view_filter_merging(8) 的执行计划为
1 #NSET2: [1, 1, 4]
2 #PRJT2: [1, 1, 4]; exp_num(2), is_atom(FALSE)
3 #SLCT2: [1, 1, 4]; T.X > 5
4 #PRJT2: [1, 1, 4]; exp_num(2), is_atom(FALSE)
5 #AAGR2: [1, 1, 4]; grp_num(0), sfun_num(1), distinct_flag[0]; slave_empty(0)
6 #CSCN2: [1, 1, 4]; INDEX33555472(T1); btr_scan(1)
此时的 SLCT2 操作符在 PRJT2 操作符上面,所以是没有下推行为的。
值为 16
- 文档例子有问题
收集公用表达式相关的所有过滤条件,改写合并所有条件,并下放到公用表达式的内部。
值为 32
TOP 信息下推到派生表。
值为 64
- 文档例子有问题
外层布尔表达式隐式声明 IS NOT NULL 属性,对派生表/视图对应的列显示添加 COL IS NOT NULL 布尔表达式。
值为 128
外层 ROWNUM 过滤表达式尝试下放至视图/派生表生成 TOP 子句。
查看以下 SQL 的执行计划
select
*
from
(
select
*,
rownum rn
from
test_lg1
order by
a1
)
where
rn < 10;
VIEW_FILTER_MERGING = 0 时的计划
1 #NSET2: [15, 5000, 64]
2 #PRJT2: [15, 5000, 64]; exp_num(4), is_atom(FALSE)
3 #SLCT2: [15, 5000, 64]; DMTEMPVIEW_889193477.RN < var1
4 #PRJT2: [11, 100000, 64]; exp_num(4), is_atom(FALSE)
5 #RN: [11, 100000, 64]
6 #BLKUP2: [11, 100000, 64]; IDX_TEST_LG1_A1(TEST_LG1)
7 #SSCN: [11, 100000, 64]; IDX_TEST_LG1_A1(TEST_LG1); btr_scan(1); is_global(0)
VIEW_FILTER_MERGING = 128 时的计划
1 #NSET2: [12, 9, 64]
2 #PRJT2: [12, 9, 64]; exp_num(4), is_atom(FALSE)
3 #PRJT2: [12, 9, 64]; exp_num(4), is_atom(FALSE)
4 #TOPN2: [11, 9, 64]; top_num(9)
5 #RN: [11, 100000, 64]
6 #BLKUP2: [11, 100000, 64]; IDX_TEST_LG1_A1(TEST_LG1)
7 #SSCN: [11, 100000, 64]; IDX_TEST_LG1_A1(TEST_LG1); btr_scan(1); is_global(0)
对比计划可以发现,将 SLCT2 操作符改为了 TOPN2,并且下放到了 PRJT2 里面。
值为 256
- 文档例子有问题
当满足以下条件时,对相关派生表过滤条件进行下推优化:
- 过滤条件对应派生表的查询项,并且是查询表达式;
- 过滤条件列映射为查询表达式的引用列,并且引用列来自派生表的
FROM项;
值为 512
视图已经有过滤条件的,不重复下放,为了后续能使用 htab。
值为 1024
包含该值时,取消下述限制:
- 视图是集合运算时的分支数应小于 10;
- 若视图是集合运算且超过 2 个分支时,过滤条件不能含有复杂函数/表达式;
查看以下 SQL 执行计划
select
/*+view_filter_merging(0)*/
*
from
(
select * from test_lg1
union all
select * from test_lg1
union all
select * from test_lg1
union all
select * from test_lg1
union all
select * from test_lg1
union all
select * from test_lg1
union all
select * from test_lg1
union all
select * from test_lg1
union all
select * from test_lg1
union all
select * from test_lg1
)
where
a1 > 1;
VIEW_FILTER_MERGING = 0 的执行计划为
1 #NSET2: [850, 50000, 52]
2 #PRJT2: [850, 50000, 52]; exp_num(2), is_atom(FALSE)
3 #SLCT2: [850, 50000, 52]; DMTEMPVIEW_889193563.A1 > 1
4 #PRJT2: [817, 1000000, 52]; exp_num(2), is_atom(FALSE)
5 #UNION ALL: [817, 1000000, 52]
6 #PRJT2: [671, 900000, 52]; exp_num(2), is_atom(FALSE)
7 #UNION ALL: [671, 900000, 52]
8 #PRJT2: [539, 800000, 52]; exp_num(2), is_atom(FALSE)
9 #UNION ALL: [539, 800000, 52]
10 #PRJT2: [422, 700000, 52]; exp_num(2), is_atom(FALSE)
11 #UNION ALL: [422, 700000, 52]
12 #PRJT2: [318, 600000, 52]; exp_num(2), is_atom(FALSE)
13 #UNION ALL: [318, 600000, 52]
14 #PRJT2: [229, 500000, 52]; exp_num(2), is_atom(FALSE)
15 #UNION ALL: [229, 500000, 52]
16 #PRJT2: [154, 400000, 52]; exp_num(2), is_atom(FALSE)
17 #UNION ALL: [154, 400000, 52]
18 #PRJT2: [92, 300000, 52]; exp_num(2), is_atom(FALSE)
19 #UNION ALL: [92, 300000, 52]
20 #PRJT2: [45, 200000, 52]; exp_num(2), is_atom(FALSE)
21 #UNION ALL: [45, 200000, 52]
22 #PRJT2: [11, 100000, 52]; exp_num(2), is_atom(FALSE)
23 #CSCN2: [11, 100000, 52]; INDEX33555467(TEST_LG1); btr_scan(1)
24 #PRJT2: [11, 100000, 52]; exp_num(2), is_atom(FALSE)
25 #CSCN2: [11, 100000, 52]; INDEX33555467(TEST_LG1); btr_scan(1)
26 #PRJT2: [11, 100000, 52]; exp_num(2), is_atom(FALSE)
27 #CSCN2: [11, 100000, 52]; INDEX33555467(TEST_LG1); btr_scan(1)
28 #PRJT2: [11, 100000, 52]; exp_num(2), is_atom(FALSE)
29 #CSCN2: [11, 100000, 52]; INDEX33555467(TEST_LG1); btr_scan(1)
30 #PRJT2: [11, 100000, 52]; exp_num(2), is_atom(FALSE)
31 #CSCN2: [11, 100000, 52]; INDEX33555467(TEST_LG1); btr_scan(1)
32 #PRJT2: [11, 100000, 52]; exp_num(2), is_atom(FALSE)
33 #CSCN2: [11, 100000, 52]; INDEX33555467(TEST_LG1); btr_scan(1)
34 #PRJT2: [11, 100000, 52]; exp_num(2), is_atom(FALSE)
35 #CSCN2: [11, 100000, 52]; INDEX33555467(TEST_LG1); btr_scan(1)
36 #PRJT2: [11, 100000, 52]; exp_num(2), is_atom(FALSE)
37 #CSCN2: [11, 100000, 52]; INDEX33555467(TEST_LG1); btr_scan(1)
38 #PRJT2: [11, 100000, 52]; exp_num(2), is_atom(FALSE)
39 #CSCN2: [11, 100000, 52]; INDEX33555467(TEST_LG1); btr_scan(1)
40 #PRJT2: [11, 100000, 52]; exp_num(2), is_atom(FALSE)
41 #CSCN2: [11, 100000, 52]; INDEX33555467(TEST_LG1); btr_scan(1)
可以看出来,SLCT2 在 PRJT2 外层,也就是条件并没有下放。
VIEW_FILTER_MERGING = 1024 的执行计划为
1 #NSET2: [93, 50000, 52]
2 #PRJT2: [93, 50000, 52]; exp_num(2), is_atom(FALSE)
3 #PRJT2: [93, 50000, 52]; exp_num(2), is_atom(FALSE)
4 #UNION ALL: [93, 50000, 52]
5 #PRJT2: [80, 45000, 52]; exp_num(2), is_atom(FALSE)
6 #UNION ALL: [80, 45000, 52]
7 #PRJT2: [68, 40000, 52]; exp_num(2), is_atom(FALSE)
8 #UNION ALL: [68, 40000, 52]
9 #PRJT2: [57, 35000, 52]; exp_num(2), is_atom(FALSE)
10 #UNION ALL: [57, 35000, 52]
11 #PRJT2: [47, 30000, 52]; exp_num(2), is_atom(FALSE)
12 #UNION ALL: [47, 30000, 52]
13 #PRJT2: [37, 25000, 52]; exp_num(2), is_atom(FALSE)
14 #UNION ALL: [37, 25000, 52]
15 #PRJT2: [28, 20000, 52]; exp_num(2), is_atom(FALSE)
16 #UNION ALL: [28, 20000, 52]
17 #PRJT2: [19, 15000, 52]; exp_num(2), is_atom(FALSE)
18 #UNION ALL: [19, 15000, 52]
19 #PRJT2: [12, 10000, 52]; exp_num(2), is_atom(FALSE)
20 #UNION ALL: [12, 10000, 52]
21 #PRJT2: [5, 5000, 52]; exp_num(2), is_atom(FALSE)
22 #BLKUP2: [5, 5000, 52]; IDX_TEST_LG1_A1(TEST_LG1)
23 #SSEK2: [5, 5000, 52]; scan_type(ASC), IDX_TEST_LG1_A1(TEST_LG1), scan_range(1,max], is_global(0)
24 #PRJT2: [5, 5000, 52]; exp_num(2), is_atom(FALSE)
25 #BLKUP2: [5, 5000, 52]; IDX_TEST_LG1_A1(TEST_LG1)
26 #SSEK2: [5, 5000, 52]; scan_type(ASC), IDX_TEST_LG1_A1(TEST_LG1), scan_range(1,max], is_global(0)
27 #PRJT2: [5, 5000, 52]; exp_num(2), is_atom(FALSE)
28 #BLKUP2: [5, 5000, 52]; IDX_TEST_LG1_A1(TEST_LG1)
29 #SSEK2: [5, 5000, 52]; scan_type(ASC), IDX_TEST_LG1_A1(TEST_LG1), scan_range(1,max], is_global(0)
30 #PRJT2: [5, 5000, 52]; exp_num(2), is_atom(FALSE)
31 #BLKUP2: [5, 5000, 52]; IDX_TEST_LG1_A1(TEST_LG1)
32 #SSEK2: [5, 5000, 52]; scan_type(ASC), IDX_TEST_LG1_A1(TEST_LG1), scan_range(1,max], is_global(0)
33 #PRJT2: [5, 5000, 52]; exp_num(2), is_atom(FALSE)
34 #BLKUP2: [5, 5000, 52]; IDX_TEST_LG1_A1(TEST_LG1)
35 #SSEK2: [5, 5000, 52]; scan_type(ASC), IDX_TEST_LG1_A1(TEST_LG1), scan_range(1,max], is_global(0)
36 #PRJT2: [5, 5000, 52]; exp_num(2), is_atom(FALSE)
37 #BLKUP2: [5, 5000, 52]; IDX_TEST_LG1_A1(TEST_LG1)
38 #SSEK2: [5, 5000, 52]; scan_type(ASC), IDX_TEST_LG1_A1(TEST_LG1), scan_range(1,max], is_global(0)
39 #PRJT2: [5, 5000, 52]; exp_num(2), is_atom(FALSE)
40 #BLKUP2: [5, 5000, 52]; IDX_TEST_LG1_A1(TEST_LG1)
41 #SSEK2: [5, 5000, 52]; scan_type(ASC), IDX_TEST_LG1_A1(TEST_LG1), scan_range(1,max], is_global(0)
42 #PRJT2: [5, 5000, 52]; exp_num(2), is_atom(FALSE)
43 #BLKUP2: [5, 5000, 52]; IDX_TEST_LG1_A1(TEST_LG1)
44 #SSEK2: [5, 5000, 52]; scan_type(ASC), IDX_TEST_LG1_A1(TEST_LG1), scan_range(1,max], is_global(0)
45 #PRJT2: [5, 5000, 52]; exp_num(2), is_atom(FALSE)
46 #BLKUP2: [5, 5000, 52]; IDX_TEST_LG1_A1(TEST_LG1)
47 #SSEK2: [5, 5000, 52]; scan_type(ASC), IDX_TEST_LG1_A1(TEST_LG1), scan_range(1,max], is_global(0)
48 #PRJT2: [5, 5000, 52]; exp_num(2), is_atom(FALSE)
49 #BLKUP2: [5, 5000, 52]; IDX_TEST_LG1_A1(TEST_LG1)
50 #SSEK2: [5, 5000, 52]; scan_type(ASC), IDX_TEST_LG1_A1(TEST_LG1), scan_range(1,max], is_global(0)
这就可以看到 SLCT2 被下放到每一个查询里面,变成了索引范围查询了。