为什么并行提示在 oracle 19c 中不起作用

Why the parallel hint is not working in oracle 19c

SELECT /*+PARALLEL 8*/
        A.ACC_ID,
         COALESCE (B.PR_ID, NULL),
         COALESCE (B.DESC, NULL),
         COALESCE (B.CNT, 0)
    FROM (SELECT ACC_ID
            FROM ACC_ID_IN
           WHERE XXX = 1 AND YYY = 'ABCD') A
         LEFT OUTER JOIN
         (  SELECT /*+PARALLEL 8*/
                  A.ACC_ID,
                   B.PR_ID,
                   B.DESC,
                   COUNT (DISTINCT A.ACC_NBR) CNT
              FROM DB1.TABLE1 A,
                   TABLE2  B,
                   TABLE3  C
                   WHERE A.ACC_ID IN (8888888888)
                   AND A.P_ID = B.P_ID
                   AND A.P_ID = C.P_ID
                   AND A.START <=TO_DATE (SUBSTR (A.ACC_ID, 1, 4) || '1231','YYYY/MM/DD')
                   AND A.END > TO_DATE (SUBSTR (A.ACC_ID, 1, 4) || '1230','YYYY/MM/DD')
          GROUP BY A.ACC_ID, B.PR_ID, B.DESC
          ORDER BY A.ACC_ID, B.PR_ID, B.DESC) B
             ON A.ACC_ID = B.ACC_ID
   WHERE A.ACC_ID IN (8888888888)
GROUP BY A.ACC_ID,
         COALESCE (B.PR_ID, NULL),
         COALESCE (B.DESC, NULL),
         COALESCE (B.CNT, 0)

上面的带有并行提示的查询需要很长时间才能执行,而当我删除并行提示时相同的查询在几秒钟内执行。当 oracle 升级到 19c 时出现此问题。您能否帮助我了解这里发生了什么,我是否需要执行任何设置以启用并行提示作为数据库升级的一部分 activity。

并行性很棘手,并行度可能出乎意料的原因有很多。以下是您的查询的潜在问题,其中一些在评论中提到:

  1. 这么快的查询你还想要并行吗?并行更努力,而不是更聪明,所以你通常只想在大对象上使用它需要很长时间来处理。如果查询在没有并行性的情况下在几秒钟内运行,那么它可能首先不是并行性的好候选者。

  2. 语句级提示 查询顶部的 /*+ PARALLEL */ 提示适用于整个语句,因此您不需要也向其他查询块添加提示。

  3. 提示格式不正确 如果要指定并行度,需要在数字两边使用括号,如/*+ PARALLEL(8) */。如果没有括号,Oracle 将计算并行度。我什至不记得所有的规则和细节,但如果你要求 Oracle 为你生成 DOP,它通常会使用 CPU_COUNT * PARALLEL_THREADS_PER_CPU * NUMBER_OF_INSTANCES.

  4. CPU_COUNT 由于您刚刚升级,请检查 CPU_COUNT 是否已更改。在某些平台上,例如 Solaris,Oracle 将每个虚拟处理器计算为 CPU,然后仍将其乘以 PARALLEL_THREADS_PER_CPU,这可能会导致荒谬的数字。虽然那个参数看起来像是你不会碰的东西,但我已经在许多系统上缩小了 CPU_COUNT 并取得了很好的效果。 运行 下面的查询查看最相关的并行参数。

     select *
     from v$parameter
     where name in ('cpu_count', 'parallel_threads_per_cpu', 'parallel_degree_policy', 'parallel_degree_limit');
    
  5. 查找并行度 有多种方法可以查找 DOP 以及查找有关选择 DOP 的原因的信息。在19c中,explain plan的“Note”和“Hint Report”部分可以给出DOP是如何计算的详细信息。使用 explain plan for select ...,然后使用 select * from table(dbms_xplan.display); 查找该信息。正如 astentx 所建议的,select dbms_sqltune.report_sql_monitor('&SQL_ID') from dual 对长 运行 查询也有很大帮助。

而不是为整个查询提供提示 - 您可以指定驱动 table。

/*+ 并行(A,8) */

然后制定解释计划,看看 DOP 是否到位。