はい、Oracleはテーブル1をusingビュークエリに結合するようにクエリを書き直します。したがって、t1.column2 = somevalue AND t1.column3 = someothervalue
が選択的であり、Oracleがこれを認識している場合は、クエリがTABLE1から駆動され、usingビューのテーブルに結合されることを計画で確認する必要があります。説明プランを実行して確認してください。すなわち
set linesize 200 pagesize 200
explain plan for
merge....;
select * from table(dbms_xplan.display());
Oracleがこれを行っていることがわかります。
例えば:
SQL> create table table1(id number primary key, t2_id number, str varchar2(20), notes varchar2(20));
Table created.
SQL> create table table2(id number primary key, notes varchar2(20));
Table created.
SQL>
SQL> insert into table1
2 select rownum, rownum, case mod(rownum, 100) when 0 then 'ONE' else 'TWO' end, null
3 from dual connect by level <=1000000;
1000000 rows created.
SQL>
SQL> insert into table2
2 select rownum, dbms_random.string('x', 10)
3 from dual connect by level <=1000000;
1000000 rows created.
SQL>
SQL> create index table1_idx on table1(str);
Index created.
SQL> exec dbms_stats.gather_table_stats(user, 'TABLE1', method_opt=>'for all indexed columns size skewonly');
PL/SQL procedure successfully completed.
SQL> exec dbms_stats.gather_table_stats(user, 'TABLE2');
PL/SQL procedure successfully completed.
t1.str = 'ONE'
非常に選択的である場合は、次のように追加します。
SQL> explain plan for
2 merge into table1 t1
3 using (select * from table2 t where t.id > 1000) t2
4 on (t2.id = t1.t2_id and t1.str = 'ONE')
5 when matched then update
6 set t1.notes = t2.notes;
Explained.
SQL> @explain ""
Plan hash value: 2050534005
---------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------------
| 0 | MERGE STATEMENT | | 441 | 11025 | 929 (5)| 00:00:12 |
| 1 | MERGE | TABLE1 | | | | |
| 2 | VIEW | | | | | |
|* 3 | HASH JOIN | | 441 | 12348 | 929 (5)| 00:00:12 |
|* 4 | TABLE ACCESS BY INDEX ROWID| TABLE1 | 441 | 5733 | 69 (2)| 00:00:01 |
|* 5 | INDEX RANGE SCAN | TABLE1_IDX | 8828 | | 21 (0)| 00:00:01 |
|* 6 | TABLE ACCESS FULL | TABLE2 | 994K| 14M| 848 (4)| 00:00:11 |
-------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - access("T"."ID"="T1"."T2_ID")
4 - filter("T1"."T2_ID">1000)
5 - access("T1"."STR"='ONE')
6 - filter("T"."ID">1000)
あなたはそれが表1に適用されたインデックスを見ることができます
INDEX RANGE SCAN | TABLE1_IDX
したがって、table1でスキャンされた多くの行を削除します(私のテーブルを考慮するとハッシュ結合の方が適切でしたが、あなたの場合、結合ステップでネストされたループアプローチが表示される場合があります)。