在一次的sql优化中,遇到SYS_OP_C2C函数,通过分析是由于一个表的varchar2和另外一个表的nvarchar2列进行关联导致,通过以下简单使用进行重现.对于这个问题,如果需要使用index,需要创建SYS_OP_C2C的函数index,或者把列类型修改一致.
SQL> create user xff identified by oracle;
用户已创建。
SQL> grant dba to xff;
授权成功。
SQL> create table xff.t1(id number,name varchar2(100));
表已创建。
SQL> insert into xff.t1 select object_id,object_name from dba_objects;
已创建 89932 行。
SQL> commit;
提交完成。
SQL> create table xff.t2(id number,name nvarchar2(100));
表已创建。
SQL> insert into xff.t2 select object_id,object_name from dba_objects;
已创建 89933 行。
SQL> commit;
提交完成。
SQL> exec dbms_stats.gather_table_stats('XFF','T1',cascade=>true);
PL/SQL 过程已成功完成。
SQL> exec dbms_stats.gather_table_stats('XFF','T2',cascade=>true);
PL/SQL 过程已成功完成。
SQL> set autot on
SQL> select count(1) from xff.t1, xff.t2 where t1.name=t2.name;
COUNT(1)
----------
160752
执行计划
----------------------------------------------------------
Plan hash value: 906334482
------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 74 | | 760 (1)| 00:00:10 |
| 1 | SORT AGGREGATE | | 1 | 74 | | | |
|* 2 | HASH JOIN | | 146K| 10M| 3256K| 760 (1)| 00:00:10 |
| 3 | TABLE ACCESS FULL| T1 | 89932 | 2195K| | 137 (1)| 00:00:02 |
| 4 | TABLE ACCESS FULL| T2 | 89933 | 4303K| | 205 (1)| 00:00:03 |
------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("T2"."NAME"=SYS_OP_C2C("T1"."NAME"))
还有一种情况也可能发生该转换,比如使用dblink的访问远程库,本地库和远程库字符集不一致.参考:SQL Statements Performed Across Database Links run Slowly. Explain Plan Shows Function SYS_OP_C2C has been Applied to Predicates, and Query uses a Full Table Scan. (Doc ID 2010872.1)