分区表上未使用索引

时间:2018-07-15 17:59:51

标签: database oracle performance indexing partitioning

我有tableA,它(列表)几乎被5个值平均分配。 tableA包含1亿行,并且在customFunc(x)上具有本地(分区)索引。以下查询使用所提到的索引执行RANGE SCAN,并执行大约5到10秒钟,并返回500万。

select count(*) from tableA where customFunc(x)='abc';

不幸的是,当我尝试在特定分区上执行相同的查询时,它会进行全表扫描,并且要花很长时间。

select count(*) from tableA where customFunc(x)='abc' and partitioning_key='DT';

我完全不明白为什么会这样。.在第二种情况下,它不应该利用分区修剪吗?

编辑:添加提示/*+ index(tableA mentionedIndex) */解决了此问题,但是我仍然不明白为什么默认情况下不使用它

编辑:XPLAN 1

Plan hash value: xxx

---------------------------------------------------------------------------------------------------------------------
| Id  | Operation           | Name                          | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
---------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |                               |     1 |    17 | 29335   (1)| 00:00:02 |       |       |
|   1 |  SORT AGGREGATE     |                               |     1 |    17 |            |          |       |       |
|   2 |   PARTITION LIST ALL|                               |  5227K|    84M| 29335   (1)| 00:00:02 |     1 |     5 |
|*  3 |    INDEX RANGE SCAN | CUSTOM_FUNC_INDEX             |  5227K|    84M| 29335   (1)| 00:00:02 |     1 |     5 |
---------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   3 - access(customFunc(x)='abc')

XPLAN 2(带有分区键)

Plan hash value: yyy

----------------------------------------------------------------------------------------------------
| Id  | Operation              | Name      | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
----------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT       |           |     1 |    30 |   679K  (2)| 00:00:27 |       |       |
|   1 |  SORT AGGREGATE        |           |     1 |    30 |            |          |       |       |
|   2 |   PARTITION LIST SINGLE|           |  4014K|   114M|   679K  (2)| 00:00:27 |   KEY |   KEY |
|*  3 |    TABLE ACCESS FULL   | tableA    |  4014K|   114M|   679K  (2)| 00:00:27 |     1 |     1 |
----------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   3 - filter(customFunc(x)='abc')

1 个答案:

答案 0 :(得分:0)

  

在第二种情况下不应该利用分区修剪吗?

第二个查询确实应用分区修剪:这就是该步骤的含义:PARTITION LIST SINGLE。问题是分区修剪意味着读取整个分区:在第二个计划中,步骤TABLE ACCESS FULL意味着读取分区中的所有行,而不使用索引。因此,第二个查询正在评估分区中的每一行的customFunc(x)='abc'

  

使用分区键创建本地索引有什么意义?

区别在于,以分区键为前缀的本地索引将始终使用分区修剪,而当本地索引不具有分区键时,优化程序可以选择是否应用分区修剪。但是,如果要运行不使用分区键的查询,那么显然需要非前缀版本。

现在您应该感到困惑。给定分区键作为谓词,优化器对指定的分区执行INDEX RANGE SCAN。要弄清楚为什么不这样做,您需要付出更多的努力。您的统计信息可能过时,或者您需要收集直方图。它是基于函数的索引这一事实可能会使优化器感到困惑。如果您有访问权限,或有合作的DBA,则可以使用10053事件来深入了解。 Find out more