删除分区 全局索引 drop partition global index Statistics变化

news2025/1/8 5:52:58

1.不一定unusable,可以先删除data (index 再删除过程中会更新结构)再drop/truncate.

----------------------

CREATE TABLE interval_sale
   ( prod_id        NUMBER(6)
   , cust_id        NUMBER
   , time_id        DATE
   )
   PARTITION BY RANGE (time_id)
   INTERVAL(NUMTOYMINTERVAL(1, 'YEAR'))
     ( PARTITION p0 VALUES LESS THAN (TO_DATE('1-1-2003', 'DD-MM-YYYY')),
       PARTITION p1 VALUES LESS THAN (TO_DATE('1-1-2004', 'DD-MM-YYYY')),
       PARTITION p2 VALUES LESS THAN (TO_DATE('1-1-2005', 'DD-MM-YYYY')),
       PARTITION p3 VALUES LESS THAN (TO_DATE('1-1-2006', 'DD-MM-YYYY'))); 
 insert into interval_sale values(1, 1, to_date('2002-01-01','yyyy-mm-dd')); 
 insert into interval_sale values(2, 2, to_date('2003-01-01','yyyy-mm-dd')); 
 insert into interval_sale values(3, 3, to_date('2004-01-01','yyyy-mm-dd'));
 insert into interval_sale values(4, 4, to_date('2005-01-01','yyyy-mm-dd'));

 commit;
 
 select *from interval_sale;
create index idx_01 on interval_sale(cust_id); 
create index idx_02 on interval_sale(prod_id) local;

 select  dp.table_name,dp.num_rows,dp.partition_name,to_char(dp.last_analyzed,'yyyymmdd HH24MISS') from dba_tab_partitions dp  where dp.table_name='INTERVAL_SALE'  ; 
 
 select di.index_name,di.num_rows,to_char(di.last_analyzed,'yyyymmdd HH24MISS'),di.partition_name,di.distinct_keys ,di.status from dba_ind_partitions di where di.index_name like 'IDX_0%'  ;
  
 select dt.table_name,dt.num_rows,to_char(dt.last_analyzed,'yyyymmdd HH24MISS') from dba_tables dt where dt.table_name='INTERVAL_SALE'  ; 
  
 select di.index_name,di.num_rows,to_char(di.last_analyzed,'yyyymmdd HH24MISS')  ,di.distinct_keys ,status from dba_indexes di where di.index_name like 'IDX_0%' ;     
 
 
 alter index idx_01 rebuild ; 
 alter index idx_02 rebuild partition P0;
 alter index idx_02 rebuild partition P1;
 alter index idx_02 rebuild partition P2;
 alter index idx_02 rebuild partition P3;
 
 alter table INTERVAL_SALE drop partition p2 UPDATE   INDEXES;
 
 alter table INTERVAL_SALE  MERGE PARTITIONS p0, p1 INTO PARTITION p01 UPDATE INDEXES;
 alter table INTERVAL_SALE  MERGE PARTITIONS p01, p3 INTO PARTITION p0123 UPDATE global INDEXES;
 alter table INTERVAL_SALE  MERGE PARTITIONS p012, p3 INTO PARTITION p0123 UPDATE   INDEXES;
 
----------------------------
     
 

㈡ 对全局索引的作用
大分区表truncate partition后,需要对全局索引进行维护,否则,global index会变成unusable
问题介绍:
① 在drop partition时,为了维护global索引,要加update indexes或是update global indexes条件
  请问,大家研究过这两个条件的区别吗?

UPDATE GLOBAL INDEXES只维护全局索引
UPDATE INDEXES同时维护全局和本地索引

对于DROP/TRUNCATE PARTITION而言 ,二者没有太大的区别
对于MERGE和SPLIT PARTITION,你就可以看到二者的区别了

-----UPDATE GLOBAL INDEXES 时 Partition 没reubild 好

---------------------坏了之后还能好,肯定是rebuild了


虽然index是变得valid了,但是index的空间没有释放
因为该操作不等于REBUILD,只是在进行DDL的时候,同步维护索引信息而已?

不太认可,虽然update indexes后row num确实没变,不太等同于rebuild index,但是这个过程中其实类似rebuild index 的。否则update会很快,不会出现上亿记录update好几分钟。

IDX_01 在drop paritition后rownum 应该会变少,但这里没变,rebuild 后会变,

上例子merge也是Partition变,global 不确定变没变,因为merge 不会改变数据,可能也不会update global的数据量的。

-------再次验证。 dba_ind_partitions 和dba_tab_partitions(之前都没变) 都会变,dba_tables,dba_indexes 不变

SQL>  select  dp.table_name,dp.num_rows,dp.partition_name,to_char(dp.last_analyzed,'yyyymmdd HH24MISS') from dba_tab_partitions dp  where dp.table_name='INTERVAL_SALE'  ;

TABLE_NAME                                                                         NUM_ROWS PARTITION_NAME                                                                   TO_CHAR(DP.LAST_ANALYZED,'YYYYMMDDHH24MISS')
-------------------------------------------------------------------------------- ---------- -------------------------------------------------------------------------------- --------------------------------------------
INTERVAL_SALE                                                                               P0                                                                               
INTERVAL_SALE                                                                               P1                                                                               
INTERVAL_SALE                                                                               P2                                                                               
INTERVAL_SALE                                                                               P3                                                                               

SQL>  select di.index_name,di.num_rows,to_char(di.last_analyzed,'yyyymmdd HH24MISS'),di.partition_name,di.distinct_keys ,di.status from dba_ind_partitions di where di.index_name like 'IDX_0%'  ;

INDEX_NAME                                                                         NUM_ROWS TO_CHAR(DI.LAST_ANALYZED,'YYYYMMDDHH24MISS') PARTITION_NAME                                                                   DISTINCT_KEYS STATUS
-------------------------------------------------------------------------------- ---------- -------------------------------------------- -------------------------------------------------------------------------------- ------------- --------
SQL>  select dt.table_name,dt.num_rows,to_char(dt.last_analyzed,'yyyymmdd HH24MISS') from dba_tables dt where dt.table_name='INTERVAL_SALE'  ;

TABLE_NAME                                                                         NUM_ROWS TO_CHAR(DT.LAST_ANALYZED,'YYYYMMDDHH24MISS')
-------------------------------------------------------------------------------- ---------- --------------------------------------------
INTERVAL_SALE                                                                               

SQL>  select di.index_name,di.num_rows,to_char(di.last_analyzed,'yyyymmdd HH24MISS')  ,di.distinct_keys ,status from dba_indexes di where di.index_name like 'IDX_0%' ;

INDEX_NAME                                                                         NUM_ROWS TO_CHAR(DI.LAST_ANALYZED,'YYYYMMDDHH24MISS') DISTINCT_KEYS STATUS
-------------------------------------------------------------------------------- ---------- -------------------------------------------- ------------- --------

SQL> 
SQL>  select  dp.table_name,dp.num_rows,dp.partition_name,to_char(dp.last_analyzed,'yyyymmdd HH24MISS') from dba_tab_partitions dp  where dp.table_name='INTERVAL_SALE'  ;

TABLE_NAME                                                                         NUM_ROWS PARTITION_NAME                                                                   TO_CHAR(DP.LAST_ANALYZED,'YYYYMMDDHH24MISS')
-------------------------------------------------------------------------------- ---------- -------------------------------------------------------------------------------- --------------------------------------------
INTERVAL_SALE                                                                               P0                                                                               
INTERVAL_SALE                                                                               P1                                                                               
INTERVAL_SALE                                                                               P2                                                                               
INTERVAL_SALE                                                                               P3                                                                               

SQL>  select di.index_name,di.num_rows,to_char(di.last_analyzed,'yyyymmdd HH24MISS'),di.partition_name,di.distinct_keys ,di.status from dba_ind_partitions di where di.index_name like 'IDX_0%'  ;

INDEX_NAME                                                                         NUM_ROWS TO_CHAR(DI.LAST_ANALYZED,'YYYYMMDDHH24MISS') PARTITION_NAME                                                                   DISTINCT_KEYS STATUS
-------------------------------------------------------------------------------- ---------- -------------------------------------------- -------------------------------------------------------------------------------- ------------- --------
IDX_02                                                                                    7 20240801 200718                              P0                                                                                           1 USABLE
IDX_02                                                                                    7 20240801 200718                              P1                                                                                           1 USABLE
IDX_02                                                                                    7 20240801 200718                              P2                                                                                           1 USABLE
IDX_02                                                                                    7 20240801 200718                              P3                                                                                           1 USABLE

SQL>  select dt.table_name,dt.num_rows,to_char(dt.last_analyzed,'yyyymmdd HH24MISS') from dba_tables dt where dt.table_name='INTERVAL_SALE'  ;

TABLE_NAME                                                                         NUM_ROWS TO_CHAR(DT.LAST_ANALYZED,'YYYYMMDDHH24MISS')
-------------------------------------------------------------------------------- ---------- --------------------------------------------
INTERVAL_SALE                                                                               

SQL>  select di.index_name,di.num_rows,to_char(di.last_analyzed,'yyyymmdd HH24MISS')  ,di.distinct_keys ,status from dba_indexes di where di.index_name like 'IDX_0%' ;

INDEX_NAME                                                                         NUM_ROWS TO_CHAR(DI.LAST_ANALYZED,'YYYYMMDDHH24MISS') DISTINCT_KEYS STATUS
-------------------------------------------------------------------------------- ---------- -------------------------------------------- ------------- --------
IDX_01                                                                                   28 20240801 200718                                          4 VALID
IDX_02                                                                                   28 20240801 200718                                          1 N/A

SQL>  alter table INTERVAL_SALE  MERGE PARTITIONS p0, p1 INTO PARTITION p01 UPDATE INDEXES;

Table altered


SQL> 
SQL>  select  dp.table_name,dp.num_rows,dp.partition_name,to_char(dp.last_analyzed,'yyyymmdd HH24MISS') from dba_tab_partitions dp  where dp.table_name='INTERVAL_SALE'  ;

TABLE_NAME                                                                         NUM_ROWS PARTITION_NAME                                                                   TO_CHAR(DP.LAST_ANALYZED,'YYYYMMDDHH24MISS')
-------------------------------------------------------------------------------- ---------- -------------------------------------------------------------------------------- --------------------------------------------
INTERVAL_SALE                                                                            14 P01                                                                              20240801 200810
INTERVAL_SALE                                                                               P2                                                                               
INTERVAL_SALE                                                                               P3                                                                               

SQL>  select di.index_name,di.num_rows,to_char(di.last_analyzed,'yyyymmdd HH24MISS'),di.partition_name,di.distinct_keys ,di.status from dba_ind_partitions di where di.index_name like 'IDX_0%'  ;

INDEX_NAME                                                                         NUM_ROWS TO_CHAR(DI.LAST_ANALYZED,'YYYYMMDDHH24MISS') PARTITION_NAME                                                                   DISTINCT_KEYS STATUS
-------------------------------------------------------------------------------- ---------- -------------------------------------------- -------------------------------------------------------------------------------- ------------- --------
IDX_02                                                                                   14 20240801 200811                              P01                                                                                          2 USABLE
IDX_02                                                                                    7 20240801 200718                              P2                                                                                           1 USABLE
IDX_02                                                                                    7 20240801 200718                              P3                                                                                           1 USABLE

SQL>  select dt.table_name,dt.num_rows,to_char(dt.last_analyzed,'yyyymmdd HH24MISS') from dba_tables dt where dt.table_name='INTERVAL_SALE'  ;

TABLE_NAME                                                                         NUM_ROWS TO_CHAR(DT.LAST_ANALYZED,'YYYYMMDDHH24MISS')
-------------------------------------------------------------------------------- ---------- --------------------------------------------
INTERVAL_SALE                                                                               

SQL>  select di.index_name,di.num_rows,to_char(di.last_analyzed,'yyyymmdd HH24MISS')  ,di.distinct_keys ,status from dba_indexes di where di.index_name like 'IDX_0%' ;

INDEX_NAME                                                                         NUM_ROWS TO_CHAR(DI.LAST_ANALYZED,'YYYYMMDDHH24MISS') DISTINCT_KEYS STATUS
-------------------------------------------------------------------------------- ---------- -------------------------------------------- ------------- --------
IDX_01                                                                                   28 20240801 200718                                          4 VALID
IDX_02                                                                                   28 20240801 200718                                          1 N/A

SQL>  alter table INTERVAL_SALE drop partition p2 UPDATE   INDEXES;

Table altered


SQL> 
SQL>  select  dp.table_name,dp.num_rows,dp.partition_name,to_char(dp.last_analyzed,'yyyymmdd HH24MISS') from dba_tab_partitions dp  where dp.table_name='INTERVAL_SALE'  ;

TABLE_NAME                                                                         NUM_ROWS PARTITION_NAME                                                                   TO_CHAR(DP.LAST_ANALYZED,'YYYYMMDDHH24MISS')
-------------------------------------------------------------------------------- ---------- -------------------------------------------------------------------------------- --------------------------------------------
INTERVAL_SALE                                                                            14 P01                                                                              20240801 200810
INTERVAL_SALE                                                                               P3                                                                               

SQL>  select di.index_name,di.num_rows,to_char(di.last_analyzed,'yyyymmdd HH24MISS'),di.partition_name,di.distinct_keys ,di.status from dba_ind_partitions di where di.index_name like 'IDX_0%'  ;

INDEX_NAME                                                                         NUM_ROWS TO_CHAR(DI.LAST_ANALYZED,'YYYYMMDDHH24MISS') PARTITION_NAME                                                                   DISTINCT_KEYS STATUS
-------------------------------------------------------------------------------- ---------- -------------------------------------------- -------------------------------------------------------------------------------- ------------- --------
IDX_02                                                                                   14 20240801 200811                              P01                                                                                          2 USABLE
IDX_02                                                                                    7 20240801 200718                              P3                                                                                           1 USABLE

SQL>  select dt.table_name,dt.num_rows,to_char(dt.last_analyzed,'yyyymmdd HH24MISS') from dba_tables dt where dt.table_name='INTERVAL_SALE'  ;

TABLE_NAME                                                                         NUM_ROWS TO_CHAR(DT.LAST_ANALYZED,'YYYYMMDDHH24MISS')
-------------------------------------------------------------------------------- ---------- --------------------------------------------
INTERVAL_SALE                                                                               

SQL>  select di.index_name,di.num_rows,to_char(di.last_analyzed,'yyyymmdd HH24MISS')  ,di.distinct_keys ,status from dba_indexes di where di.index_name like 'IDX_0%' ;

INDEX_NAME                                                                         NUM_ROWS TO_CHAR(DI.LAST_ANALYZED,'YYYYMMDDHH24MISS') DISTINCT_KEYS STATUS
-------------------------------------------------------------------------------- ---------- -------------------------------------------- ------------- --------
IDX_01                                                                                   28 20240801 200718                                          4 VALID
IDX_02                                                                                   28 20240801 200718                                          1 N/A

SQL> 

-----------------------------1---------------

下面的情况为什么会慢的原因是,truncate后,可能更新了Statistics,导致了分区的num rows=0,所以其后的执行计划都是错误的。 在有数据的情况下rebuild index,Oracle 会更新index Statistics. table的Statistics不变。 


 13亿记录的大表truncate后来接着晚上有人继续插入这个表的时候,告诉我慢的要命,(truncate后有人手动更新了Statistics

本来一个小时至少可以跑完400万条记录,现在3个小时了才跑130万
 我马上想到会不会是本地索引问题,因为我听说虽然分区交换或者TRUNCATE对局部索引没影响,
  但是实际上是有问题的,还是重建的好(gather Statistics 更好):
  alter index bill.UNQ_RRATING_CHARGE_D_591_0712 rebuild partition PART_20
  把这个刚才我TRUNCATE的分区的涉及到的局部索引重新建了一下
  结果立马见效果了,10分钟跑了200万条记录,600万条记录在20分钟全部跑好!比以前同期跑的还快一点

---DDL重新index会更新index 的Statistics, truncate 不会。

               

CREATE TABLE interval_sale
   ( prod_id        NUMBER(6)
   , cust_id        NUMBER
   , time_id        DATE
   )
   PARTITION BY RANGE (time_id)
   INTERVAL(NUMTOYMINTERVAL(1, 'YEAR'))
     ( PARTITION p0 VALUES LESS THAN (TO_DATE('1-1-2003', 'DD-MM-YYYY')),
       PARTITION p1 VALUES LESS THAN (TO_DATE('1-1-2004', 'DD-MM-YYYY')),
       PARTITION p2 VALUES LESS THAN (TO_DATE('1-1-2005', 'DD-MM-YYYY')),
       PARTITION p3 VALUES LESS THAN (TO_DATE('1-1-2006', 'DD-MM-YYYY'))); 
 insert into interval_sale values(1, 1, to_date('2002-01-01','yyyy-mm-dd')); 
 insert into interval_sale values(2, 2, to_date('2003-01-01','yyyy-mm-dd')); 
 insert into interval_sale values(3, 3, to_date('2004-01-01','yyyy-mm-dd'));
 insert into interval_sale values(4, 4, to_date('2005-01-01','yyyy-mm-dd'));

 commit;
 
 select *from interval_sale
create index idx_01 on interval_sale(cust_id);
select table_name, index_name, partitioned, status
   from user_indexes where table_name='INTERVAL_SALE';
 
 create index idx_02 on interval_sale(prod_id) local;

 select dp.table_owner,dp.table_name,dp.num_rows,dp.partition_name,dp.last_analyzed from dba_tab_partitions dp 
 where dp.table_name='INTERVAL_SALE'  ; 
 
 select di.index_owner,di.index_name,di.num_rows,di.last_analyzed,di.partition_name,di.distinct_keys 
 from dba_ind_partitions di where di.index_name like 'IDX_0%'  ;
 
 
 select dt.owner,dt.table_name,dt.num_rows, dt.last_analyzed from dba_tables dt where dt.table_name='INTERVAL_SALE'  ; 
  
  select di.owner,di.index_name,di.num_rows,di.last_analyzed  ,di.distinct_keys from dba_indexes di 
 where di.index_name like 'IDX_0%' ;     
 
 
 alter index idx_01 rebuild ;
 
  alter index idx_02 rebuild partition P0;
  alter index idx_02 rebuild partition P1;
  alter index idx_02 rebuild partition P2;
  alter index idx_02 rebuild partition P3;

SQL>  select dp.table_owner,dp.table_name,dp.num_rows,dp.partition_name,dp.last_analyzed from dba_tab_partitions dp
  2   where dp.table_name='INTERVAL_SALE'  ;

TABLE_OWNER                                                                      TABLE_NAME                                                                         NUM_ROWS PARTITION_NAME                                                                   LAST_ANALYZED
-------------------------------------------------------------------------------- -------------------------------------------------------------------------------- ---------- -------------------------------------------------------------------------------- -------------
AAA                                                                       INTERVAL_SALE                                                                               P0                                                                               
AAA                                                                       INTERVAL_SALE                                                                               P1                                                                               
AAA                                                                       INTERVAL_SALE                                                                               P2                                                                               
AAA                                                                       INTERVAL_SALE                                                                               P3                                                                               

------分区表上Statistics为空

SQL>  select di.index_owner,di.index_name,di.num_rows,di.last_analyzed,di.partition_name,di.distinct_keys
  2   from dba_ind_partitions di where di.index_name like 'IDX_0%'  ;

INDEX_OWNER                                                                      INDEX_NAME                                                                         NUM_ROWS LAST_ANALYZED PARTITION_NAME                                                                   DISTINCT_KEYS
-------------------------------------------------------------------------------- -------------------------------------------------------------------------------- ---------- ------------- -------------------------------------------------------------------------------- -------------
AAA                                                                       IDX_02                                                                                    0 01/08/2024 6: P0                                                                                           0
AAA                                                                       IDX_02                                                                                    0 01/08/2024 6: P1                                                                                           0
AAA                                                                       IDX_02                                                                                    1 01/08/2024 6: P2                                                                                           1
AAA                                                                       IDX_02                                                                                    1 01/08/2024 6: P3                                                                                           1

-----index 先插入记录再创建 index ,自动更新,但是创建完index 再insert,不会更新。

SQL>  select dt.owner,dt.table_name,dt.num_rows, dt.last_analyzed from dba_tables dt where dt.table_name='INTERVAL_SALE'  ;

OWNER                                                                            TABLE_NAME                                                                         NUM_ROWS LAST_ANALYZED
-------------------------------------------------------------------------------- -------------------------------------------------------------------------------- ---------- -------------
AAA                                                                       INTERVAL_SALE                                                    

---- table上面也是空的                          

SQL>   select di.owner,di.index_name,di.num_rows,di.last_analyzed  ,di.distinct_keys from dba_indexes di
  2   where di.index_name like 'IDX_0%' ;

OWNER                                                                            INDEX_NAME                                                                         NUM_ROWS LAST_ANALYZED DISTINCT_KEYS
-------------------------------------------------------------------------------- -------------------------------------------------------------------------------- ---------- ------------- -------------
AAA                                                                       IDX_01                                                                                    2 01/08/2024 6:             2
AAA                                                                       IDX_02                                                                                    2 01/08/2024 6:             1

----分区也是,先建再加会显示


SQL>  insert into interval_sale values(1, 1, to_date('2002-01-01','yyyy-mm-dd'));

1 row inserted


SQL>  insert into interval_sale values(2, 2, to_date('2003-01-01','yyyy-mm-dd'));

1 row inserted


SQL>  insert into interval_sale values(3, 3, to_date('2004-01-01','yyyy-mm-dd'));

1 row inserted


SQL>  insert into interval_sale values(4, 4, to_date('2005-01-01','yyyy-mm-dd'));

1 row inserted

----------进一步验证  index创建后插入数据没有任何改变
SQL> 
SQL>  select dp.table_owner,dp.table_name,dp.num_rows,dp.partition_name,dp.last_analyzed from dba_tab_partitions dp
  2   where dp.table_name='INTERVAL_SALE'  ;

TABLE_OWNER                                                                      TABLE_NAME                                                                         NUM_ROWS PARTITION_NAME                                                                   LAST_ANALYZED
-------------------------------------------------------------------------------- -------------------------------------------------------------------------------- ---------- -------------------------------------------------------------------------------- -------------
AAA                                                                       INTERVAL_SALE                                                                               P0                                                                               
AAA                                                                       INTERVAL_SALE                                                                               P1                                                                               
AAA                                                                       INTERVAL_SALE                                                                               P2                                                                               
AAA                                                                       INTERVAL_SALE                                                                               P3                                                                               

SQL>  select di.index_owner,di.index_name,di.num_rows,di.last_analyzed,di.partition_name,di.distinct_keys
  2   from dba_ind_partitions di where di.index_name like 'IDX_0%'  ;

INDEX_OWNER                                                                      INDEX_NAME                                                                         NUM_ROWS LAST_ANALYZED PARTITION_NAME                                                                   DISTINCT_KEYS
-------------------------------------------------------------------------------- -------------------------------------------------------------------------------- ---------- ------------- -------------------------------------------------------------------------------- -------------
AAA                                                                       IDX_02                                                                                    0 01/08/2024 6: P0                                                                                           0
AAA                                                                       IDX_02                                                                                    0 01/08/2024 6: P1                                                                                           0
AAA                                                                       IDX_02                                                                                    1 01/08/2024 6: P2                                                                                           1
AAA                                                                       IDX_02                                                                                    1 01/08/2024 6: P3                                                                                           1

SQL>  select dt.owner,dt.table_name,dt.num_rows, dt.last_analyzed from dba_tables dt where dt.table_name='INTERVAL_SALE'  ;

OWNER                                                                            TABLE_NAME                                                                         NUM_ROWS LAST_ANALYZED
-------------------------------------------------------------------------------- -------------------------------------------------------------------------------- ---------- -------------
AAA                                                                       INTERVAL_SALE                                                                               

SQL>   select di.owner,di.index_name,di.num_rows,di.last_analyzed  ,di.distinct_keys from dba_indexes di
  2   where di.index_name like 'IDX_0%' ;

OWNER                                                                            INDEX_NAME                                                                         NUM_ROWS LAST_ANALYZED DISTINCT_KEYS
-------------------------------------------------------------------------------- -------------------------------------------------------------------------------- ---------- ------------- -------------
AAA                                                                       IDX_01                                                                                    2 01/08/2024 6:             2
AAA                                                                       IDX_02                                                                                    2 01/08/2024 6:             1

----------------------DDL on index,index Statistics 会变---------------------------

SQL> alter index idx_01  rebuild;


SQL> 
SQL>  select dp.table_owner,dp.table_name,dp.num_rows,dp.partition_name,dp.last_analyzed from dba_tab_partitions dp
  2   where dp.table_name='INTERVAL_SALE'  ;

TABLE_OWNER                                                                      TABLE_NAME                                                                         NUM_ROWS PARTITION_NAME                                                                   LAST_ANALYZED
-------------------------------------------------------------------------------- -------------------------------------------------------------------------------- ---------- -------------------------------------------------------------------------------- -------------
AAA                                                                       INTERVAL_SALE                                                                               P0                                                                               
AAA                                                                       INTERVAL_SALE                                                                               P1                                                                               
AAA                                                                       INTERVAL_SALE                                                                               P2                                                                               
AAA                                                                       INTERVAL_SALE                                                                               P3                                                                               

SQL>  select di.index_owner,di.index_name,di.num_rows,di.last_analyzed,di.partition_name,di.distinct_keys
  2   from dba_ind_partitions di where di.index_name like 'IDX_0%'  ;

INDEX_OWNER                                                                      INDEX_NAME                                                                         NUM_ROWS LAST_ANALYZED PARTITION_NAME                                                                   DISTINCT_KEYS
-------------------------------------------------------------------------------- -------------------------------------------------------------------------------- ---------- ------------- -------------------------------------------------------------------------------- -------------
AAA                                                                       IDX_02                                                                                    0 01/08/2024 6: P0                                                                                           0
AAA                                                                       IDX_02                                                                                    0 01/08/2024 6: P1                                                                                           0
AAA                                                                       IDX_02                                                                                    1 01/08/2024 6: P2                                                                                           1
AAA                                                                       IDX_02                                                                                    1 01/08/2024 6: P3                                                                                           1

SQL>  select dt.owner,dt.table_name,dt.num_rows, dt.last_analyzed from dba_tables dt where dt.table_name='INTERVAL_SALE'  ;

OWNER                                                                            TABLE_NAME                                                                         NUM_ROWS LAST_ANALYZED
-------------------------------------------------------------------------------- -------------------------------------------------------------------------------- ---------- -------------
AAA                                                                       INTERVAL_SALE                                                                               

SQL>   select di.owner,di.index_name,di.num_rows,di.last_analyzed  ,di.distinct_keys from dba_indexes di
  2   where di.index_name like 'IDX_0%' ;

OWNER                                                                            INDEX_NAME                                                                         NUM_ROWS LAST_ANALYZED DISTINCT_KEYS
-------------------------------------------------------------------------------- -------------------------------------------------------------------------------- ---------- ------------- -------------
AAA                                                                       IDX_01                                                                                    8 01/08/2024 6:             4
AAA                                                                       IDX_02                                                                                    2 01/08/2024 6:             1

SQL> 
SQL>   alter index idx_02 rebuild partition P0;

Index altered


SQL>   alter index idx_02 rebuild partition P1;

Index altered


SQL>   alter index idx_02 rebuild partition P2;

Index altered


SQL>   alter index idx_02 rebuild partition P3;

Index altered


SQL> 
SQL> 
SQL>  select dp.table_owner,dp.table_name,dp.num_rows,dp.partition_name,dp.last_analyzed from dba_tab_partitions dp
  2   where dp.table_name='INTERVAL_SALE'  ;

TABLE_OWNER                                                                      TABLE_NAME                                                                         NUM_ROWS PARTITION_NAME                                                                   LAST_ANALYZED
-------------------------------------------------------------------------------- -------------------------------------------------------------------------------- ---------- -------------------------------------------------------------------------------- -------------
AAA                                                                       INTERVAL_SALE                                                                               P0                                                                               
AAA                                                                       INTERVAL_SALE                                                                               P1                                                                               
AAA                                                                       INTERVAL_SALE                                                                               P2                                                                               
AAA                                                                       INTERVAL_SALE                                                                               P3                                                                               

SQL>  select di.index_owner,di.index_name,di.num_rows,di.last_analyzed,di.partition_name,di.distinct_keys
  2   from dba_ind_partitions di where di.index_name like 'IDX_0%'  ;

INDEX_OWNER                                                                      INDEX_NAME                                                                         NUM_ROWS LAST_ANALYZED PARTITION_NAME                                                                   DISTINCT_KEYS
-------------------------------------------------------------------------------- -------------------------------------------------------------------------------- ---------- ------------- -------------------------------------------------------------------------------- -------------
AAA                                                                       IDX_02                                                                                    2 01/08/2024 6: P0                                                                                           1
AAA                                                                       IDX_02                                                                                    2 01/08/2024 6: P1                                                                                           1
AAA                                                                       IDX_02                                                                                    2 01/08/2024 6: P2                                                                                           1
AAA                                                                       IDX_02                                                                                    2 01/08/2024 6: P3                                                                                           1

SQL>  select dt.owner,dt.table_name,dt.num_rows, dt.last_analyzed from dba_tables dt where dt.table_name='INTERVAL_SALE'  ;

OWNER                                                                            TABLE_NAME                                                                         NUM_ROWS LAST_ANALYZED
-------------------------------------------------------------------------------- -------------------------------------------------------------------------------- ---------- -------------
AAA                                                                       INTERVAL_SALE                                                                               

SQL>   select di.owner,di.index_name,di.num_rows,di.last_analyzed  ,di.distinct_keys from dba_indexes di
  2   where di.index_name like 'IDX_0%' ;

OWNER                                                                            INDEX_NAME                                                                         NUM_ROWS LAST_ANALYZED DISTINCT_KEYS
-------------------------------------------------------------------------------- -------------------------------------------------------------------------------- ---------- ------------- -------------
AAA                                                                       IDX_01                                                                                    8 01/08/2024 6:             4
AAA                                                                       IDX_02                                                                                    2 01/08/2024 6:             1

SQL> drop index IDX_02;

Index dropped


SQL> create index idx_02 on interval_sale(prod_id) local;

Index created

 
SQL>  select dp.table_owner,dp.table_name,dp.num_rows,dp.partition_name,dp.last_analyzed from dba_tab_partitions dp
  2   where dp.table_name='INTERVAL_SALE'  ;

TABLE_OWNER                                                                      TABLE_NAME                                                                         NUM_ROWS PARTITION_NAME                                                                   LAST_ANALYZED
-------------------------------------------------------------------------------- -------------------------------------------------------------------------------- ---------- -------------------------------------------------------------------------------- -------------
AAA                                                                       INTERVAL_SALE                                                                               P0                                                                               
AAA                                                                       INTERVAL_SALE                                                                               P1                                                                               
AAA                                                                       INTERVAL_SALE                                                                               P2                                                                               
AAA                                                                       INTERVAL_SALE                                                                               P3                                                                               

SQL>  select di.index_owner,di.index_name,di.num_rows,di.last_analyzed,di.partition_name,di.distinct_keys
  2   from dba_ind_partitions di where di.index_name like 'IDX_0%'  ;

INDEX_OWNER                                                                      INDEX_NAME                                                                         NUM_ROWS LAST_ANALYZED PARTITION_NAME                                                                   DISTINCT_KEYS
-------------------------------------------------------------------------------- -------------------------------------------------------------------------------- ---------- ------------- -------------------------------------------------------------------------------- -------------
AAA                                                                       IDX_02                                                                                    2 01/08/2024 6: P0                                                                                           1
AAA                                                                       IDX_02                                                                                    2 01/08/2024 6: P1                                                                                           1
AAA                                                                       IDX_02                                                                                    2 01/08/2024 6: P2                                                                                           1
AAA                                                                       IDX_02                                                                                    2 01/08/2024 6: P3                                                                                           1

SQL>  select dt.owner,dt.table_name,dt.num_rows, dt.last_analyzed from dba_tables dt where dt.table_name='INTERVAL_SALE'  ;

OWNER                                                                            TABLE_NAME                                                                         NUM_ROWS LAST_ANALYZED
-------------------------------------------------------------------------------- -------------------------------------------------------------------------------- ---------- -------------
AAA                                                                       INTERVAL_SALE                                                                               

SQL>   select di.owner,di.index_name,di.num_rows,di.last_analyzed  ,di.distinct_keys from dba_indexes di
  2   where di.index_name like 'IDX_0%' ;

OWNER                                                                            INDEX_NAME                                                                         NUM_ROWS LAST_ANALYZED DISTINCT_KEYS
-------------------------------------------------------------------------------- -------------------------------------------------------------------------------- ---------- ------------- -------------
AAA                                                                       IDX_01                                                                                    8 01/08/2024 6:             4
AAA                                                                       IDX_02                                                                                    8 01/08/2024 6:             1

SQL> 

-----------------2--------------------

 为什么下面会慢,因为update global indexes对于Partitiontable,他的并行会对表的,比如有10个分区,起10个并行,那么一个分区只有一个并行,如果10个分区只有一个分区有数据,那么另外9个分区都在等最后一个分区rebuild. 相当于并行没有生效。


  半夜被叫起来干活了
  奇怪,如下写法怎么半天都执行不好
  alter table bill.recur_rating_charge_d_591_0712 truncate partition PART_21  update global indexes  ;

  select count(*) from bill.recur_rating_charge_d_591_0712 partition(PART_21)
  数据始终不变
  但是我看v$session_longops看到这个SID很快就做好事了,
  而我看表分区记录始终在
  我晕,只好采用老办法,杀掉会话后,
  alter table bill.RECUR_RATING_CHARGE_d_591_0712 truncate partition PART_20不加update global indexes
  然后分别维护了普通索引和局部索引,这次加NOLOGGING和PARALLEL 8 ,也很快,3亿的大表,维护普通索引只花了200秒
  alter index bill.IDX_CHARGE_D_591_0712_SID rebuild  parallel 8 nologging ;
  alter index bill.UNQ_RRATING_CHARGE_D_591_0712 rebuild partition PART_21 parallel 8 nologging;
  猜测原因:
  truncate partition PART_20后,这个分区的和这个分区上的本地索引的统计信息是不会更新也不会丢失
  当我往这个分区插入数据的时候,执行计划是根据错误的统计信息生成的,所以会很慢
  当我rebuild index partition PART_20 后,会导致这个索引的统计信息丢失,
  而我的执行计划就有可能改变了,所以我的插入变快了

 
  当你truncate后应该立即对这个分区做分析cascade => true(增加对索引的统计信息),
  同时rebuild global index 并分析global index才对

㈢ 空间释放问题
其实空间等都已经释放了,但数据字典没有被更新,
例如你查dba_segments视图,发现这个分区的bytes其实还为原来的大小
我们可执行alter table **** allocate extent即可更新数据字典为正常状态
例如针对范围分区如下操作:
alter table *** modify partition PART_*** allocate extent;

我们先从实验,了解这个问题,首先创建分区表,他存在4个分区,每个分区中,都存在数据,

SQL> CREATE TABLE interval_sale
  2  ( prod_id        NUMBER(6)
  3  , cust_id        NUMBER
  4  , time_id        DATE
  5  )
  6  PARTITION BY RANGE (time_id)
  7  INTERVAL(NUMTOYMINTERVAL(1, 'YEAR'))
  8    ( PARTITION p0 VALUES LESS THAN (TO_DATE('1-1-2003', 'DD-MM-YYYY')),
  9      PARTITION p1 VALUES LESS THAN (TO_DATE('1-1-2004', 'DD-MM-YYYY')),
 10      PARTITION p2 VALUES LESS THAN (TO_DATE('1-1-2005', 'DD-MM-YYYY')),
 11      PARTITION p3 VALUES LESS THAN (TO_DATE('1-1-2006', 'DD-MM-YYYY')));

SQL> insert into interval_sale values(1, 1, to_date('2002-01-01','yyyy-mm-dd'));
1 row created.

SQL> insert into interval_sale values(2, 2, to_date('2003-01-01','yyyy-mm-dd'));
1 row created.

SQL> insert into interval_sale values(3, 3, to_date('2004-01-01','yyyy-mm-dd'));
1 row created.

SQL> insert into interval_sale values(4, 4, to_date('2005-01-01','yyyy-mm-dd'));
1 row created.

SQL> commit;
Commit complete.

创建全局索引,当前状态是VALID,

SQL> create index idx_01 on interval_sale(cust_id);
Index created.

SQL> select table_name, index_name, partitioned, status
  2  from user_indexes where table_name='INTERVAL_SALE';
TABLE_NAME       INDEX_NAME      PARTITIONED  STATUS
--------------- --------------- ------------ --------
INTERVAL_SALE    IDX_01          NO           VALID
删除第一个分区,
SQL> alter table interval_sale drop partition for (to_date('2002-01-01','yyyy-mm-dd'));
Table altered.

此时,看到这个全局索引是UNUSABLE的状态,和我们的设想是相同的,即删除分区,会导致全局索引的失效,

SQL> select table_name, index_name, status
  2  from user_indexes where table_name='INTERVAL_SALE';
TABLE_NAME       INDEX_NAME      STATUS
--------------- --------------- ----------
INTERVAL_SALE    IDX_01          UNUSABLE

结论告诉我们,删除分区,确实会导致全局索引的失效,我们从问题入手,为什么分区删除,会导致全局索引的失效?

我们知道,Oracle中索引是以B树的结构存储的,包括了索引键值、rowid信息,而且按照索引键值有序排列,当通过索引扫描需要回表的时候,能利用rowid直接定位到索引键值对应的数据块,这是最快的数据访问方式。当我们删除表中数据的时候,同时要删除他对应的索引,由于索引是有序排列的,如果要删除一条索引数据,他的组织结构,就需要调整,以保证正确的排列顺序,12c之前,因为某种原因,无法在删除分区的同时,对索引重新构建,所以此时索引的状态是失效的,与其是错的,宁可不让用,删除分区,需要手工rebuild重建索引才能让其生效,

图片

我们换种思路,之所以全局索引的状态失效,根本问题就是索引对应的分区中数据被删除了,那么,如果不删除分区中的数据,索引结构无需任何调整,他的状态是不是就是正常的?

首先重建索引,让其生效,

SQL> alter index idx_01 rebuild online;
Index altered.

SQL> select table_name, index_name, status
  2  from user_indexes where table_name='INTERVAL_SALE';
TABLE_NAME       INDEX_NAME      STATUS
--------------- --------------- --------
INTERVAL_SALE    IDX_01          VALID

此时,通过delete删除即将删除的第二个分区的数据,

SQL> delete from interval_sale where time_id <= to_date('2003-01-01','yyyy-mm-dd');
1 row deleted.

SQL> commit;
Commit complete.

再次执行分区删除的操作,

SQL> alter table interval_sale drop partition for (to_date('2003-01-01','yyyy-mm-dd'));
Table altered.

此时,再看全局索引,他的状态正常,VALID,并未因为分区删除的操作,导致其失效,

SQL> select table_name, index_name, status
  2  from user_indexes where table_name='INTERVAL_SALE';
TABLE_NAME       INDEX_NAME      STATUS
--------------- --------------- --------
INTERVAL_SALE    IDX_01          VALID

通过以上实验,可以得到结论,如果待删除的分区中没有任何数据,执行分区删除,不会导致全局索引状态的失效。原因已经说了,因为分区删除时,不存在任何数据需要删除,意味着无需调整索引结构,所以全局索引的状态,就无需置为失效,这个算是对待分区删除避免全局索引失效的一种另类解决方案了。

通过这个问题,能让我体会到的,就是一个看着很简单的问题背后,其实蕴涵着丰富的知识,同时对待任何一个知识点,从原理层理解地越深入,找到问题的本质,就可以让你和真相更近,豁然开朗,这可能就需要日常的积累,碰到问题的时候,多问一句为什么,就可能让你大开眼界,这就是Oracle以及技术领域最吸引人的地方了。---屁话,这是oracle进行改进了原因

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1969449.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

前端面试宝典【HTML篇】【4】

欢迎来到《前端面试宝典》,这里是你通往互联网大厂的专属通道,专为渴望在前端领域大放异彩的你量身定制。通过本专栏的学习,无论是一线大厂还是初创企业的面试,都能自信满满地展现你的实力。 核心特色: 独家实战案例:每一期专栏都将深入剖析真实的前端面试案例,从基础知…

C++回顾——虚析构

一、示例代码 #include<iostream> using namespace std;class Weapon { public:virtual void getWeapon() 0;//virtual ~Weapon() default; };class bow :public Weapon { public:void getWeapon() override{cout << "弓箭 " << ends;}~bow(){c…

支持对接OpenAI、Ollama和本地向量模型,MaxKB开源知识库问答系统发布v1.4.0版本

2024年8月1日&#xff0c;MaxKB开源知识库问答系统正式发布v1.4.0版本。在这一版本中&#xff0c;MaxKB的社区版支持对接OpenAI、Ollama和本地的向量模型&#xff0c;并且支持设置模型的使用权限&#xff0c;同时MaxKB还支持知识库自定义向量模型。 自v1.4.0版本开始&#xff…

坐牢第二十一天 20240801(IO)

一.作业 1、使用两个线程完成两个文件的拷贝&#xff0c;分支线程1拷贝前一半&#xff0c;分支线程2拷贝后一半&#xff0c;主线程回收两个分支线程的资源 #include <myhead.h> struct Node {char *src;char *dest;int start;int len; }; //定义求源文件大小的函数 int…

python爬虫初识

一、什么互联网 互联网&#xff08;Internet&#xff09;是全球范围内最大的计算机网络&#xff0c;它将数以百万计的私人、公共、学术、商业和政府网络通过一系列标准通信协议&#xff08;如TCP/IP&#xff09;连接起来形成的一个庞大的国际网络。 互联网的起源可以追溯到196…

【C++】1.C++入门(1)

文章目录 1.C关键字2.命名空间2.1 命名空间定义2.2 命名空间使用 3.C输入&输出4.缺省参数4.1 缺省参数概念4.2 缺省参数分类 5.函数重载5.1 函数重载概念5.2 C支持函数重载的原理--名字修饰(name Mangling) 1.C关键字 C总计63个关键字&#xff0c;C语言32个关键字 2.命名空…

0206创建场景状态的基础接口

一、创建一个类 二、写一个类&#xff0c;作为接口类的作用&#xff08;不一定是interface&#xff09;

ctfshow 大赛原题 web689--web695

web689 <?php error_reporting(0); if(isset($_GET) && !empty($_GET)){$url $_GET[file];$path "upload/".$_GET[path];}else{show_source(__FILE__);exit(); }if(strpos($path,..) > -1){ //检查 $path 是否包含 ..&#xff0c;以防止路径注…

Podman 发布 v5.2.0-RC3

这是 v5.2.0 的最终候选版本。以下是初步的发布说明。 功能 Podman 现在支持使用 libkrun 作为在 MacOS 上创建虚拟机的后端。libkrun 后端的优势在于允许将 GPU 挂载到虚拟机中以加速任务。默认后端仍然是 applehv。Quadlet 现在支持.build 文件&#xff0c;这使得可以由 Quad…

2024PDF编辑工具新趋势:从基础到高级的全方位方案

随着数字化办公的发展&#xff0c;我们对PDF编辑的需求也日益增长。从最开始对文字的修改到现在可以插入音频、视频文件。这些都离不开PDF编辑软件的功劳&#xff0c;那有什么好用的PDF编辑工具呢&#xff0c;听我娓娓道来。 1.福昕PDF编辑器 直达链接&#xff1a;https://e…

【轨物方案】分布式光伏电站运维智能化升级方案

分布式光伏电站从2010年开始在国内推广&#xff0c;到2022年底&#xff0c;全国工商业分布式光伏电站装机容量为157.62GW&#xff0c;并且新增装机量逐年递增。以1MW/电站计算&#xff0c;保守估计全国至少已有十几万个工商业分布式光伏电站。 这些电站的运维工作是往往交给专业…

百度松果菁英班作业整理(第一期)

本期的题目比较简单&#xff0c;最后两题稍微复杂&#xff0c;但是主题思路也不难&#xff0c;大家可以一起练习。 孪生质数 在质数中&#xff0c;若两个质数之差为2,我们称之为孪生质数,例如(3、5)(5、7)&#xff0c;输入2个正整数&#xff0c;判断他是不是孪生质数,输出YE…

大数据技术原理-MapReduce的应用

摘要 本实验报告详细阐述了在“大数据技术原理”课程中进行的MapReduce编程实验。实验环境基于Hadoop平台和Ubuntu操作系统。实验的核心内容包括使用MapReduce编程模型实现文件的合并去重、排序以及对给定表格信息的挖掘。实验过程中&#xff0c;我们首先在Hadoop分布式文件系…

基于统计检验与随机森林分析不同天气类型的影响因素

1.项目背景 本项目使用了一个人工合成的天气数据集&#xff0c;模拟了雨天、晴天、多云和雪天四种类型&#xff0c;在分析过程中&#xff0c;对数据进行了异常值处理&#xff0c;并通过描述性统计对数据进行了初步探索&#xff0c;接着&#xff0c;使用Kruskal-Wallis检验、Du…

Flutter连接iPad报错Developer Mode

Flutter连接iPad报错Developer Mode To use 黑色iPad for development, enable Developer Mode in Settings → Privacy & Security.根据错误提示&#xff0c;在ipad中的“安全性”中没有“开发者模型”选项。 打开安全模式步骤: 需要打开Xcode,连接iPad, 在iPad中点击“…

app逆向抓包技巧:ROOT检测绕过

本篇博客旨在记录学习过程&#xff0c;不可用于商用等其它途径 场景 某监管app查壳发现使用了 《梆梆企业版》 加固&#xff0c;想尝试使用frida-dexdump脱壳&#xff0c;打开app发现提示下图样式&#xff0c;由于进不去界面&#xff0c;我们直接脱壳无法保证能获取到完整的 …

虚拟机windows server创建域

目录 准备工作 一、新建域控制器 二、提升为域控制器添加新林 三、新建组织单位&#xff08;OU&#xff09;&#xff0c;用户 四、将计算机加域 五、在域控中管理计算机 六、在域控中配置组策略 七、域内计算机验证组策略配置 准备工作 安装域前&#xff0c;如果有DNS…

Golang | Leetcode Golang题解之第310题最小高度树

题目&#xff1a; 题解&#xff1a; func findMinHeightTrees(n int, edges [][]int) []int {if n 1 {return []int{0}}g : make([][]int, n)deg : make([]int, n)for _, e : range edges {x, y : e[0], e[1]g[x] append(g[x], y)g[y] append(g[y], x)deg[x]deg[y]}q : []i…

二百五十二、OceanBase——Linux上安装OceanBase数据库(二)

一、目的 在OBD页面上部署OceanBase数据库时发现&#xff0c;需要把新用户也要配置ssh免密登录 二、前提 root用户已经设置免密登录 三、配置步骤 1 切换到新用户obadmin [roothurys23 ~]# su obadmin 2 执行命令生成秘钥文件 [obadminhurys23 oceanbase]$ ssh-keygen …

限免下载:715页 | 2024民营企业数字化转型典型案例集

一、前言 数字化转型不仅仅是技术的更新换代&#xff0c;它涉及到企业运营模式、组织架构、企业文化等多个层面的深刻变革。通过数字化&#xff0c;企业能够更好地理解市场动态&#xff0c;提升决策效率&#xff0c;优化客户体验&#xff0c;并最终实现业务增长和价值创造。 …