ITPub博客

首页 > 数据库 > Oracle > [20250717]UNNEST提示Correlation column in SELECT, GROUP BY, or ORDER BY.txt

[20250717]UNNEST提示Correlation column in SELECT, GROUP BY, or ORDER BY.txt

原创 Oracle 作者:lfree 时间:2025-07-18 21:12:21 0 删除 编辑

[20250717]UNNEST提示Correlation column in SELECT, GROUP BY, or ORDER BY.txt

--//通过例子说明。
1.环境:
SCOTT@book01p> @ver2
==============================
PORT_STRING                   : x86_64/Linux 2.4.xx
VERSION                       : 21.0.0.0.0
BANNER                        : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
BANNER_FULL                   : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
Version 21.3.0.0.0
BANNER_LEGACY                 : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
CON_ID                        : 0
PL/SQL procedure successfully completed.

2.测试例子:
--//生产系统sql语句相对复杂,写一个简单例子:
$ cat g7.txt
select  * from dept
  where not exists (
    select /*+ &1 */ &2
      from emp
      where dept.deptno = emp.deptno
  ) ;
--//注意执行需要2个参数。

4.测试:
SCOTT@book01p> @ sl all
alter session set statistics_level = all;
Session altered.

SCOTT@book01p> @ g7.txt '' dname
    DEPTNO DNAME                          LOC
---------- ------------------------------ -------------
        40 OPERATIONS                     BOSTON
--//注意第2个字段dname来自表dept。

SCOTT@book01p> @ dpc '' outline ''
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID  1n80f4jpyrd29, child number 0
-------------------------------------
select  * from dept   where not exists (     select /*+  */ dname
from emp       where dept.deptno = emp.deptno   )
Plan hash value: 3547749009
---------------------------------------------------------------------------------------------------------------------
| Id  | Operation          | Name | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | A-Rows |   A-Time   | Buffers |
---------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |      1 |        |       |     9 (100)|          |      1 |00:00:00.01 |      28 |
|*  1 |  FILTER            |      |      1 |        |       |            |          |      1 |00:00:00.01 |      28 |
|   2 |   TABLE ACCESS FULL| DEPT |      1 |      4 |    80 |     3   (0)| 00:00:01 |      4 |00:00:00.01 |       7 |
|*  3 |   TABLE ACCESS FULL| EMP  |      4 |      2 |     6 |     2   (0)| 00:00:01 |      3 |00:00:00.01 |      21 |
---------------------------------------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
   1 - SEL$1
   2 - SEL$1 / "DEPT"@"SEL$1"
   3 - SEL$2 / "EMP"@"SEL$2"
Outline Data
-------------
  /*+
      BEGIN_OUTLINE_DATA
      IGNORE_OPTIM_EMBEDDED_HINTS
      OPTIMIZER_FEATURES_ENABLE('21.1.0')
      DB_VERSION('21.1.0')
      ALL_ROWS
      OUTLINE_LEAF(@"SEL$2")
      OUTLINE_LEAF(@"SEL$1")
      FULL(@"SEL$1" "DEPT"@"SEL$1")
      PQ_FILTER(@"SEL$1" SERIAL)
      FULL(@"SEL$2" "EMP"@"SEL$2")
      END_OUTLINE_DATA
  */
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter( IS NULL)
   3 - filter("EMP"."DEPTNO"=:B1)
--//执行计划使用nest,id=1采用FILTER,导致执行效率低下,4次全表扫描emp表,逻辑读28。

--//如果参数2使用常量,注也可以使用emp的某个字段,效果一样。
SCOTT@book01p> @ g7.txt '' 1
    DEPTNO DNAME                          LOC
---------- ------------------------------ -------------
        40 OPERATIONS                     BOSTON

SCOTT@book01p> @ dpc '' outline ''

PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID  4t34fkagctx63, child number 0
-------------------------------------
select  * from dept   where not exists (     select /*+  */ 1
from emp       where dept.deptno = emp.deptno   )
Plan hash value: 1353548327
-------------------------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                    | Name    | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
-------------------------------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |         |      1 |        |       |     6 (100)|          |      1 |00:00:00.01 |       8 |       |       |          |
|   1 |  MERGE JOIN ANTI             |         |      1 |      1 |    23 |     6  (17)| 00:00:01 |      1 |00:00:00.01 |       8 |       |       |          |
|   2 |   TABLE ACCESS BY INDEX ROWID| DEPT    |      1 |      4 |    80 |     2   (0)| 00:00:01 |      4 |00:00:00.01 |       2 |       |       |          |
|   3 |    INDEX FULL SCAN           | PK_DEPT |      1 |      4 |       |     1   (0)| 00:00:01 |      4 |00:00:00.01 |       1 |       |       |          |
|*  4 |   SORT UNIQUE                |         |      4 |     12 |    36 |     4  (25)| 00:00:01 |      3 |00:00:00.01 |       6 |  2048 |  2048 | 2048  (0)|
|   5 |    TABLE ACCESS FULL         | EMP     |      1 |     12 |    36 |     3   (0)| 00:00:01 |     14 |00:00:00.01 |       6 |       |       |          |
-------------------------------------------------------------------------------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
   1 - SEL$5DA710D3
   2 - SEL$5DA710D3 / "DEPT"@"SEL$1"
   3 - SEL$5DA710D3 / "DEPT"@"SEL$1"
   5 - SEL$5DA710D3 / "EMP"@"SEL$2"
Outline Data
-------------
  /*+
      BEGIN_OUTLINE_DATA
      IGNORE_OPTIM_EMBEDDED_HINTS
      OPTIMIZER_FEATURES_ENABLE('21.1.0')
      DB_VERSION('21.1.0')
      ALL_ROWS
      OUTLINE_LEAF(@"SEL$5DA710D3")
      UNNEST(@"SEL$2")
      OUTLINE(@"SEL$1")
      OUTLINE(@"SEL$2")
      INDEX(@"SEL$5DA710D3" "DEPT"@"SEL$1" ("DEPT"."DEPTNO"))
      FULL(@"SEL$5DA710D3" "EMP"@"SEL$2")
      LEADING(@"SEL$5DA710D3" "DEPT"@"SEL$1" "EMP"@"SEL$2")
      USE_MERGE(@"SEL$5DA710D3" "EMP"@"SEL$2")
      END_OUTLINE_DATA
  */
Predicate Information (identified by operation id):
---------------------------------------------------
   4 - access("DEPT"."DEPTNO"="EMP"."DEPTNO")
       filter("DEPT"."DEPTNO"="EMP"."DEPTNO")
--//不管连接方式如何,逻辑读下降许多。

5.强制使用提示unnest看看:

SCOTT@book01p> @ g7.txt 'unnest' dname
    DEPTNO DNAME                          LOC
---------- ------------------------------ -------------
        40 OPERATIONS                     BOSTON

SCOTT@book01p> @ dpc '' outline ''
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID  8rbqcqwvytd2b, child number 0
-------------------------------------
select  * from dept   where not exists (     select /*+ unnest */ dname
      from emp       where dept.deptno = emp.deptno   )
Plan hash value: 3547749009
---------------------------------------------------------------------------------------------------------------------
| Id  | Operation          | Name | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | A-Rows |   A-Time   | Buffers |
---------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |      1 |        |       |     9 (100)|          |      1 |00:00:00.01 |      28 |
|*  1 |  FILTER            |      |      1 |        |       |            |          |      1 |00:00:00.01 |      28 |
|   2 |   TABLE ACCESS FULL| DEPT |      1 |      4 |    80 |     3   (0)| 00:00:01 |      4 |00:00:00.01 |       7 |
|*  3 |   TABLE ACCESS FULL| EMP  |      4 |      2 |     6 |     2   (0)| 00:00:01 |      3 |00:00:00.01 |      21 |
---------------------------------------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
   1 - SEL$1
   2 - SEL$1 / "DEPT"@"SEL$1"
   3 - SEL$2 / "EMP"@"SEL$2"
Outline Data
-------------
  /*+
      BEGIN_OUTLINE_DATA
      IGNORE_OPTIM_EMBEDDED_HINTS
      OPTIMIZER_FEATURES_ENABLE('21.1.0')
      DB_VERSION('21.1.0')
      ALL_ROWS
      OUTLINE_LEAF(@"SEL$2")
      OUTLINE_LEAF(@"SEL$1")
      FULL(@"SEL$1" "DEPT"@"SEL$1")
      PQ_FILTER(@"SEL$1" SERIAL)
      FULL(@"SEL$2" "EMP"@"SEL$2")
      END_OUTLINE_DATA
  */

Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter( IS NULL)
   3 - filter("EMP"."DEPTNO"=:B1)
Hint Report (identified by operation id / Query Block Name / Object Alias):
Total hints for statement: 1 (U - Unused (1))
---------------------------------------------------------------------------
   3 -  SEL$2
         U -  unnest / Correlation column in SELECT, GROUP BY, or ORDER BY
53 rows selected.

--//注意看提示:U -  unnest / Correlation column in SELECT, GROUP BY, or ORDER BY
--//oracle认为not exist 查询里面存在不相干的列,导致提示unnest无效。

--//更正该问题很简单,直接使用1个常量即可。

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/267265/viewspace-3091651/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
熟悉oracle相关技术,擅长sql优化,rman备份与恢复,熟悉linux shell编程。

注册时间:2008-01-03

  • 博文量
    4006
  • 访问量
    7969275