Oracle 使用 PARALLEL 优化计划降低查询性能

Posted

技术标签:

【中文标题】Oracle 使用 PARALLEL 优化计划降低查询性能【英文标题】:Oracle slow query performance with PARALLEL optimization plan 【发布时间】:2015-05-14 22:44:10 【问题描述】:

我的查询很简单

SELECT
    A
FROM table
    where B = 'X'

解释一下它的计划

|

   0 | SELECT STATEMENT        |                             |     2 |    16 |     4   (0)| 00:00:01 |        |      |            |

|   1 |  PX COORDINATOR         |                             |       |       |            |          |        |      |            |

|   2 |   PX SEND QC (RANDOM)   | :TQ10000                    |     2 |    16 |     4   (0)| 00:00:01 |  Q1,00 | P->S | QC (RAND)  |

|   3 |    PX BLOCK ITERATOR    |                             |     2 |    16 |     4   (0)| 00:00:01 |  Q1,00 | PCWC |            |

|*  4 |     INDEX FAST FULL SCAN| TABLE_UNIQUE_ROLES_KEY1     |     2 |    16 |     4   (0)| 00:00:01 |  Q1,00 | PCWP |            |

在我看来,Oracle 试图运行 PARALLEL 执行计划。 但我不明白它为什么会这样做。它显着减慢查询速度

如果我这样做了

SELECT /*+ NO_PARALLEL */
        A
    FROM table
        where B = 'X'

它工作得很快,计划是:

----------------------------------------------------------------------------------------------------
| Id  | Operation            | Name                        | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |                             |     2 |    16 |     4   (0)| 00:00:01 |

|*  1 |  INDEX FAST FULL SCAN| TABLE_UNIQUE_ROLES_KEY1     |     2 |    16 |     4   (0)| 00:00:01 |
----------------------------------------------------------------------------------------------------

在第一种情况下导致并行的原因是什么?

表上的degree 设置为1,但TABLE_UNIQUE_ROLES_KEY1(以及表上的其他索引)上的degree 都设置为4。我没有查询v$parameter 的权限所以我看不到如何为数据库配置并行度。

TABLE_UNIQUE_ROLES_KEY1 是查询的覆盖索引——它在列上定义(abcd),其中a 是我选择的列, b 是我要过滤的列,cd 不参与查询。

【问题讨论】:

您在数据库级别 (show parameter parallel) 有哪些并行设置?表的dba_tablesdba_indexes 中的degree 和计划正在使用的索引(或表上的所有索引)是什么?另外,TABLE_UNIQUE_ROLES_KEY1 的定义是什么(它索引了哪些列)? 表的 DEGREE = 1,TABLE_UNIQUE_ROLES_KEY1 的 DEGREE = 4,它索引 4 列。无法并行运行显示参数 - 它失败了。实际上所有索引都有 DEGREE = 4 和 Tables = 1 定义“失败”?您是否收到 Oracle 错误?如果是这样,什么错误?你用什么工具运行这个?如果您正在使用不支持 SQL*Plus 命令的东西,例如show,您可以查询gv$parameter。为什么您的索引设置为 4 级?您是否在其他地方使用它来鼓励使用并行查询?还是某些 DBA 可能运行了不必要的脚本来重建无意中更改了并行设置的索引?索引涵盖哪 4 列(即它是 'a'、'b'、'c'、'd' 或 'b'、'a'、'c'、'd' 或其他东西的索引)? 索引在 a、b、c d 上。为了。我正在运行 Oracle SQL Developer,错误是“显示参数查询失败”。不幸的是,我没有正确的权限,可能这就是节目失败的原因。我不知道为什么索引设置为 4。而且我不使用任何东西来鼓励并行查询,至少我不知道。但我们不应该这样做。它可能是 DBA 做到的,但不能确定。可以默认设置为4吗?这会是个问题吗? 【参考方案1】:

直接原因是有人告诉 Oracle 它应该使用并行查询(索引的degree 已全部设置为 4)。这往往会使优化器认为并行完全扫描索引会相对便宜,这就是优化器选择该计划的原因。

您可以更改索引上的并行设置

ALTER INDEX TABLE_UNIQUE_ROLES_KEY1 NOPARALLEL

这应该会阻止优化器选择此计划(您可能还必须将其他索引设置为noparallel,以防止优化器选择不同的索引以并行进行全扫描)。但我会犹豫是否这样做,直到我了解是哪个人或进程将您的索引上的 degree 设置为 4 - 如果您不了解根本原因,您最终可能会破坏其他东西或在无休止的战斗中,那个人/进程将您的索引设置为使用并行性,然后您将它们设置回去。

导致索引的degree 为 4 的两个最有可能的原因是某人(开发人员或 DBA)正试图让并行查询进入其他查询,或者 DBA 正在运行一个(几乎肯定是不必要的)脚本,该脚本会定期重建并行执行的索引,而没有意识到这会更改索引上的degree 设置并使得并行查询很可能启动。所以您可能需要与其他开发人员和/或其他 DBA 确定将索引设置为 noparallel 是否会对他们产生负面影响,以及是否有其他进程会更改您的设置。

【讨论】:

贾斯汀,这感觉是非常合理的解释。如果程度是导致并行查询启动的原因,我需要弄清楚它是如何到达那里的。尽管在我的开发盒上查询运行平稳,但没有并行查询,尽管机器功能要弱得多。 @antohoho - 您的本地盒子上的度数设置为 4 吗?还是1?还是默认?系统级并行设置也可能不同。既然你说你没有权限看到这些,我就忽略了这些可能性。 设置为 4,不是我的本地盒子,它是一个开发盒子。而且我没有遇到与产品盒相同的问题。我没有特权 @antohoho - 统计数据或设置的差异完全有可能导致不同环境中的不同行为。将 degree 设置为 4 是对并行扫描索引的有力推动,但这不是保证。将索引设置为 noparallel 可能是防止考虑并行查询的最简单方法。 谢谢贾斯汀,至少我知道该往哪个方向看。将尝试联系我们的 DBA。

以上是关于Oracle 使用 PARALLEL 优化计划降低查询性能的主要内容,如果未能解决你的问题,请参考以下文章

对oracle中SQL优化的理解

Oracle parallel_max_servers 提示

Oracle之 等待事件log file sync + log file parallel write (awr优化)

Oracle-第一篇一些调优技巧

Oracle面试题

Oracle 选择查询优化