【问题标题】:Partitioned Table index not working分区表索引不起作用
【发布时间】:2015-05-30 14:02:35
【问题描述】:

我有一张如下表:

CREATE TABLE MYTAB_TEST
(
  COBDATE                  NUMBER(9)            DEFAULT 0,
  SYSTEM                   VARCHAR2(3 BYTE)     DEFAULT ' ',
  BATCH_ID                 VARCHAR2(4 BYTE)     DEFAULT ' ',
  BATCH_TYPE               VARCHAR2(3 BYTE)     DEFAULT ' ',
  LOAD_TYPE                VARCHAR2(3 BYTE)     DEFAULT ' '
  )
  PARTITION BY RANGE (COBDATE)
    SUBPARTITION BY RANGE (COBDATE)
(  
  PARTITION P_POS_2014 VALUES LESS THAN (20150101)
  )
                )
  ( SUBPARTITION P_2014_JAN_01 VALUES LESS THAN (20140102)      TABLESPACE FOOTC_DATA,
    SUBPARTITION P_2014_JAN_02 VALUES LESS THAN (20140103)      TABLESPACE FOOTC_DATA,
    SUBPARTITION P_2014_JAN_03 VALUES LESS THAN (20140104)      TABLESPACE FOOTC_DATA,
    SUBPARTITION P_2014_JAN_04 VALUES LESS THAN (20140105)      TABLESPACE FOOTC_DATA,
    SUBPARTITION P_2014_JAN_05 VALUES LESS THAN (20140106)      TABLESPACE FOOTC_DATA,
    SUBPARTITION P_2014_JAN_06 VALUES LESS THAN (20140107)      TABLESPACE FOOTC_DATA,
    SUBPARTITION P_2014_JAN_07 VALUES LESS THAN (20140108)      TABLESPACE FOOTC_DATA,
    ---
    ---
    --
    so on ..

)

这个表有每天的分区。

我已经为它创建了本地索引,并且这个表每天有 100 万行的负载。 由于我们正在为特定日期的表运行删除,因此需要花费大量时间来完成状态 并且还检查了我的删除查询没有使用带有解释计划的索引。

在 MYTAB_TEST(COBDATE,SYSTEM,BATCH_ID,LOAD_TYPE) 上创建本地索引 H_POS_LOCAL_IDX

我的删除查询:

delete from MYTAB_TEST where cobdate =20150306 and system ='M' and batch_id='N1' and batch_type='S' and load_type='S ;

计划表输出:

Plan hash value: 822252374

---------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation             | Name       | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |    TQ  |IN-OUT| PQ Distrib |
---------------------------------------------------------------------------------------------------------------------------------
|   0 | DELETE STATEMENT      |            |  1880K|    23M|  1533   (1)| 00:00:19 |       |       |        |      |            |
|   1 |  DELETE               | MYTAB_TEST |       |       |            |          |       |       |        |      |            |
|   2 |   PX COORDINATOR      |            |       |       |            |          |       |       |        |      |            |
|   3 |    PX SEND QC (RANDOM)| :TQ10000   |  1880K|    23M|  1533   (1)| 00:00:19 |       |       |  Q1,00 | P->S | QC (RAND)  |
|   4 |     PX BLOCK ITERATOR |            |  1880K|    23M|  1533   (1)| 00:00:19 |    66 |    66 |  Q1,00 | PCWC |            |
|*  5 |      TABLE ACCESS FULL| MYTAB_TEST |  1880K|    23M|  1533   (1)| 00:00:19 |   432 |   432 |  Q1,00 | PCWP |            |
---------------------------------------------------------------------------------------------------------------------------------

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

   5 - filter("COBDATE"=20150306 AND "SYSTEM"='M' AND "BATCH_ID"='N1' AND "LOAD_TYPE"='L')

为什么不使用 index ?我应该在表上实现全局分区索引吗? 是因为我使用键分区列作为索引列吗?不确定

【问题讨论】:

  • 为什么要按年分区,然后按月进行子分区?为什么不只是按月分区?您无缘无故地添加了抽象层。另外,将日期存储为数字? {颤抖}你最好将它们存储为日期,或者至少,优化器会更好。至于为什么不使用索引,可能数据量大,对子分区做 fts 会更快。
  • 我已经将每天的分区实现为子分区(意思是一年的 365 个子分区)等等明年..根据设计我必须存储 cobdate 列作为数字数据类型。您能否详细说明 FTS?关于子分区? @Boneist
  • 它真的会进行全表扫描吗?它至少应该限于子分区。
  • 抱歉,我错过了您在当天进行子分区的事实。重点仍然存在;您从按年分区然后在当天进行子分区,而不是首先在当天进行分区! FTS 表示全表扫描。正如@Wernfried 所说,应该进行(子)分区修剪,这意味着 FTS 应该只发生在该子分区上,而不是整个表上。您应该编辑您的问题并提供执行计划,以便我们对您所看到的内容有更多的了解。
  • 请记住:索引仅在您搜索“少数”记录时才有帮助。如果你想访问一个更大的集合,你应该使用更有效的方法(截断,创建删除表,分区交换)

标签: sql oracle indexing oracle11g database-partitioning


【解决方案1】:

所以你想删除大约 200 万行,正如 @ibre5041 所说和我所说,oracle 不会使用索引。您可以使用分区交换:

我,你照常加载你的桌子,没关系

ii,而不是从所需的较小数据集创建“临时”表 /with create table as select, or insert with append hint, 当然在两者中并行/

iii,之后可以和临时表交换子分区,子分区只包含“正确”的数据

所以删除被跳过

【讨论】:

    【解决方案2】:

    您的起始分区和结束分区相同(423)。因此进行了分区修剪。 "FULL TABLE SCAN" 单分区可能是最好的解决方案。

    您从该分区中删除了多少行(百分比)? 怎么样:

    delete from MYTAB_TEST subpartition(yyyy)
    where cobdate =20150306 and system ='M' 
       and batch_id='N1' and batch_type='S' and load_type='S ;
    

    明确声明应该影响哪个分区?执行计划会改变吗?

    已编辑:partition_extension_clause fixed

    【讨论】:

    • 我正在从该分区中删除大约 200 万行。我已尝试使用您的删除代码,但它不起作用。@ibre5041
    • 您必须将 xxx 和 yyy 替换为特定的分区名称。删除2M时不值得使用索引。对分区进行全扫描(或分区交换)将是最好的解决方案
    • 是的,我尝试用我的分区名称替换 xxx 和 yyy,它显示 ORA-00933: SQL 命令未正确结束。但在这种情况下截断是有效的,但我希望它在哪里删除条件,因为我需要删除表上的特定批处理文件。无论如何感谢您的评论。
    猜你喜欢
    • 2020-06-11
    • 1970-01-01
    • 2017-05-29
    • 2017-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-17
    相关资源
    最近更新 更多