环境:ORACLE DB 19.20 版本
测试用例
SQL> create table t100 as select * from dba_objects;
SQL> create index idx_substr_object_name on t100 (substr(object_name,1,4));
SQL> create index idx_object_name on t100(object_name);
SQL> create table t200 as select * from dba_objects;
SQL> create index idx_t200 on t200(object_name);
SQL> select /*+use_hash(a) use_hash(b)*/ count(*) from t100 a,t200 b where a.object_name=b.object_name;
COUNT(*)
----------
705590
SQL> set lines 1000 pages 1000
SQL> select * from table(dbms_xplan.display_cursor(FORMAT=>'ADVANCED'));
PLAN_TABLE_OUTPUT
------------------------------------------------------
SQL_ID bpkc4rb5vu9y3, child number 0
-------------------------------------
select /*+use_hash(a) use_hash(b)*/ count(*) from t100 a,t200 b where
a.object_name=b.object_name
Plan hash value: 3047534014
--------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | | 696 (100)| |
| 1 | SORT AGGREGATE | | 1 | 76 | | | |
|* 2 | HASH JOIN | | 111K| 8294K| 3792K| 696 (1)| 00:00:01 |
| 3 | INDEX FAST FULL SCAN| IDX_T200 | 86239 | 2779K| | 143 (0)| 00:00:01 |
| 4 | INDEX FAST FULL SCAN| IDX_OBJECT_NAME | 86159 | 3618K| | 143 (0)| 00:00:01 |
--------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("A"."OBJECT_NAME"="B"."OBJECT_NAME" AND
SUBSTR("OBJECT_NAME",1,4)=SUBSTR("B"."OBJECT_NAME",1,4))
问题: 为什么“谓词信息”中显示“SUBSTR("OBJECT_NAME",1,4)=SUBSTR("B"."OBJECT_NAME",1,4))”?
它看起来有点像优化器智能。 Oracle 经常添加它知道在逻辑上保证产生相同结果的谓词(如果它认为这些谓词有助于提高性能)。最常见的情况是,它将“
IS NOT NULL
”添加到可为空列的内部联接列,因为它知道没有 NULL
连接键会产生结果,从而可能会缩小哈希联接输入的大小。您找到的这个可能很相似。
您在
SUBSTR(object_name,1,4)
上创建了基于函数的索引。如果您添加匹配谓词,您不仅拥有一个可能有用的索引,而且您还拥有一个隐藏的虚拟列(请参阅 user_tab_cols
),也可能有一个统计扩展(user_stat_extensions
),并且那些统计数据可能在优化器的后续计算中以某种方式有用。