【发布时间】:2018-12-23 08:25:08
【问题描述】:
我有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')
【问题讨论】:
-
谢谢斯图尔特。优化器的决策涉及多个因素,包括统计信息、可用资源、索引等。查看这两个查询的优化器计划将很有用。您能否将 xplans 添加到问题中?
-
10053 trace是你的朋友是这样的情况... -
@alexgibbs 请看上面的计划,谢谢!
-
谢谢斯图尔特,这有帮助。看起来它正在使用分区,而不是使用索引 - 我还没有足够的信心来回答并且会对此进行一些实验,但是从这些计划中的基数来看,我想知道优化器是否看到索引因为在该分区中没有足够的选择性,而是选择了完整的。看看不同谓词的行为是否相同——
customFunc(x)='VOLTRON'或其他什么而不是'abc',以及直方图是什么样的,将会很有趣。 -
Stuart 只是一个后续。我想知道您是否可以检查目标分区中“abc”谓词的相对基数。此查询是否获取大量目标分区?假设是最新的统计数据、历史数据等(没有什么是陈旧的?),看看这里是否可能涉及数据倾斜会很好。 customFunc(x) 上的零匹配谓词是否也进行全扫描?谢谢
标签: database oracle performance indexing partitioning