我的查询非常简单
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,但degree
上的TABLE_UNIQUE_ROLES_KEY1
(以及表格中的其他索引)都设置为4.我不知道' t具有查询v$parameter
的权限,因此我无法看到如何为数据库配置并行性。
TABLE_UNIQUE_ROLES_KEY1
是查询的覆盖索引 - 它是在列{(1}},a
,b
,c
)上定义的,其中{ {1}}是我选择的列,d
是我过滤的列,a
和b
不参与查询。< / p>
答案 0 :(得分:1)
直接原因是有人告诉Oracle它应该使用并行查询(索引的degree
全部设置为4)。这往往会使优化器认为并行完全扫描索引相对便宜,这就是优化器选择该计划的原因。
您可以更改索引上的并行设置
ALTER INDEX TABLE_UNIQUE_ROLES_KEY1 NOPARALLEL
应该阻止优化器选择此计划(您可能必须将其他索引设置为noparallel
以防止优化器并行选择不同的索引到完全扫描)。但是我会毫不犹豫地这样做,直到我理解了什么人或过程将你的索引上的degree
设置为4--如果你不理解根本原因,你可能最终会破坏某些东西否则或在无休止的战斗中,该人/进程设置您的索引以使用并行性并将其设置回来。
导致索引的degree
为4的两个最可能的候选者是某人(开发人员或DBA)试图获取并行查询以启用其他查询或者DBA正在运行一个(几乎肯定是不必要的)脚本,它会定期重建并行执行此操作的索引,而不会意识到这会更改索引上的degree
设置并使并行查询可能会启动。所以您可能需要与其他开发人员和/或其他DBA聊天,以确定将索引设置为noparallel
是否会对他们产生负面影响,以及是否有其他流程会改变您的设置。