Oracle慢速查询性能与PARALLEL优化计划



我有一个非常简单的查询

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试图运行并行执行计划。但我不明白它为什么会这样做。它显著降低了查询

的速度。

如果我做了

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是查询的覆盖索引——它定义在列(a, b, c, d)上,其中a是我选择的列,b是我要过滤的列,cd不涉及查询。

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

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

ALTER INDEX TABLE_UNIQUE_ROLES_KEY1 NOPARALLEL

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

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

最新更新