执行计划与预期不符

sag*_*agi 8 sql oracle performance sql-execution-plan

我遇到了一些奇怪的东西,我无法解释.

我正在使用以下查询:

MERGE INTO Main_Table t
USING  Stg_Table s 
 ON(s.site_id = t.site_id)
 WHEN MATCHED THEN
   UPDATE SET t.arpu_prev_period = s.arpu_prev_period 
              .... --50 more columns  
  where  t.period_code = 201612
Run Code Online (Sandbox Code Playgroud)

Stg_Table:索引(Site_Id)

Main_Table:
- 索引(Period_code,Site_id)
- 由period_code分区
- 注 - 我尝试在Site_Id单独的,相同的执行计划上添加索引.

我期望一个使用单分区扫描的执行计划,但我得到了Partition list all.

这是执行计划:

6   |   0 | MERGE STATEMENT       |                               |
7   |   1 |  MERGE                | Main_Table                    |
8   |   2 |   VIEW                |                               |
9   |   3 |    HASH JOIN          |                               |
10  |   4 |     TABLE ACCESS FULL | Stg_Table                     |
11  |   5 |     PARTITION LIST ALL|                               |
12  |   6 |      TABLE ACCESS FULL| Main_Table                    |
Run Code Online (Sandbox Code Playgroud)

编辑:为了澄清,如果它是不明确的,我不是在寻找如何让Oracle只扫描单个分区的答案,我已经知道,放置t.period_code = 201612在在ON条款将被罚款.我的问题是 - 为什么oracle不评估WHERE应该只过滤特定分区的子句?

Dav*_*itz 2

看起来 UPDATE 的 WHERE 子句根本没有优化。

create table t (n,x) as select level n,-1 x from dual connect by level <= 1000000;
create table s (n,x) as select level n,-1 x from dual connect by level <= 1000000;
Run Code Online (Sandbox Code Playgroud)
merge into t
using s
on (s.n = t.n)
when matched then update set t.x = s.x where 1=2
;
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述