两个表是使用hash join进行join的,join条件中没有substr。为什么谓词信息中会出现substr?

问题描述 投票:0回答:1

环境:ORACLE DB 19.20 版本

测试用例

  1. 创建表和索引。
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);
  1. 使用use_hash提示查询并获取真正的执行计划。
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 join hash
1个回答
0
投票

它看起来有点像优化器智能。 Oracle 经常添加它知道在逻辑上保证产生相同结果的谓词(如果它认为这些谓词有助于提高性能)。最常见的情况是,它将“

IS NOT NULL
”添加到可为空列的内部联接列,因为它知道没有
NULL
连接键会产生结果,从而可能会缩小哈希联接输入的大小。您找到的这个可能很相似。

您在

SUBSTR(object_name,1,4)
上创建了基于函数的索引。如果您添加匹配谓词,您不仅拥有一个可能有用的索引,而且您还拥有一个隐藏的虚拟列(请参阅
user_tab_cols
),也可能有一个统计扩展(
user_stat_extensions
),并且那些统计数据可能在优化器的后续计算中以某种方式有用。

© www.soinside.com 2019 - 2024. All rights reserved.