我有一个非常简单的查询
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
是我要过滤的列,c
和d
不涉及查询。
直接原因是有人告诉Oracle应该使用并行查询(索引的degree
都设置为4)。这往往会使优化器认为并行完全扫描索引将相对便宜,这就是优化器选择该计划的原因。
您可以更改索引的并行设置
ALTER INDEX TABLE_UNIQUE_ROLES_KEY1 NOPARALLEL
应该阻止优化器选择此计划(您可能还必须将其他索引设置为noparallel
,以防止优化器选择不同的索引进行并行完全扫描)。但是,在我了解是什么人或进程将索引上的degree
设置为4之前,我会犹豫是否这样做——如果你不了解根本原因,很可能你最终会破坏其他东西,或者在那个人/进程将索引设置为使用并行而你将它们设置回来的无休止的战斗中。
导致索引的degree
值为4的两个最可能的原因是,有人(开发人员或DBA)试图为其他查询启动并行查询,或者DBA正在运行一个(几乎肯定是不必要的)脚本,该脚本定期并行地重建索引,而没有意识到这会改变索引上的degree
设置,并使并行查询很可能启动。因此,您可能需要与其他开发人员和/或其他dba进行交谈,以弄清楚将索引设置为noparallel
是否会对他们产生负面影响,以及是否有其他进程将更改您的设置。