删除分区 全局索引 drop partition global index Statistics变化
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 USABLESQL> 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/ASQL> alter table INTERVAL_SALE MERGE PARTITIONS p0, p1 INTO PARTITION p01 UPDATE INDEXES;Table alteredSQL>
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 USABLESQL> 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/ASQL> alter table INTERVAL_SALE drop partition p2 UPDATE INDEXES;Table alteredSQL>
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 USABLESQL> 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/ASQL>
-----------------------------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_sale2 ( prod_id NUMBER(6)3 , cust_id NUMBER4 , time_id DATE5 )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, status2 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, status2 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, status2 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, status2 from user_indexes where table_name='INTERVAL_SALE';
TABLE_NAME INDEX_NAME STATUS
--------------- --------------- --------
INTERVAL_SALE IDX_01 VALID
通过以上实验,可以得到结论,如果待删除的分区中没有任何数据,执行分区删除,不会导致全局索引状态的失效。原因已经说了,因为分区删除时,不存在任何数据需要删除,意味着无需调整索引结构,所以全局索引的状态,就无需置为失效,这个算是对待分区删除避免全局索引失效的一种另类解决方案了。
通过这个问题,能让我体会到的,就是一个看着很简单的问题背后,其实蕴涵着丰富的知识,同时对待任何一个知识点,从原理层理解地越深入,找到问题的本质,就可以让你和真相更近,豁然开朗,这可能就需要日常的积累,碰到问题的时候,多问一句为什么,就可能让你大开眼界,这就是Oracle以及技术领域最吸引人的地方了。---屁话,这是oracle进行改进了原因
相关文章:
删除分区 全局索引 drop partition global index Statistics变化
1.不一定unusable,可以先删除data (index 再删除过程中会更新结构)再drop/truncate. ---------------------- CREATE TABLE interval_sale ( prod_id NUMBER(6) , cust_id NUMBER , time_id DATE ) PARTITION BY RANGE (time_i…...
git回退未commit、回退已commit、回退已push、合并某一次commit到另一个分支
文章目录 1、git回退未commit2、git回退已commit3、git回退已push的代码3.1 直接丢弃某一次的push3.2 撤销push后,不丢弃改动,重新修改后要再次push 4、合并某一次commit到另一个分支 整理几个工作上遇到的git问题。 1、git回退未commit git回退未comm…...
yolov8pose 部署rknn(rk3588)、部署地平线Horizon、部署TensorRT,部署工程难度小、模型推理速度快,DFL放后处理中
特别说明:参考官方开源的yolov8代码、瑞芯微官方文档、地平线的官方文档,如有侵权告知删,谢谢。 模型和完整仿真测试代码,放在github上参考链接 模型和代码。 之前写了yolov8、yolov8seg、yolov8obb 的 DFL 放在模型中和放在后处理…...
程序员找工作之操作系统面试题总结分析
程序员在找工作面试时,操作系统方面可能会被问到的问题涵盖了多个核心知识点和概念。以下是对这些面试问题的总结和分析: 1. 核心硬件与体系结构 微机的核心部件:询问微机硬件系统中最核心的部件是什么(CPU)。处理机…...
TypeScript 迭代器和生成器详解
目录 迭代器(Iterators) 生成器(Generators) 使用场景 for..of vs. for..in 语句 for..of 循环 for..in 循环 区别总结 注意事项 总结 在 TypeScript 中,迭代器(Iterators)和生成器&am…...
echarts 极坐标柱状图 如何定义柱子颜色
目录 echarts 极坐标柱状图 如何定义柱子颜色问题描述方式一 在 series 数组中定义颜色方式二 通过 colorBy 和 color 属性配合使用 echarts 极坐标柱状图 如何定义柱子颜色 本文将分享在使用 echarts 的 极坐标柱状图 时,如何自定义柱子的颜色。问题本身并不难解决…...
JavaScript模块化
JavaScript模块化 一、CommonJS规范1、在node环境下的模块化导入、导出 2、浏览器环境下使用模块化browserify编译js 二、ES6模块化规范1、在浏览器端的定义和使用2、在node环境下简单使用方式一:方式二: 3、导出数据4、导入数据5、数据引用问题 一、Com…...
文件包含漏洞Tomato靶机渗透_详解
一、导入靶机 将下载好的靶机拖入到VMware中,填写靶机机名称(随便起一个)和路径 虚拟机设置里修改网络状态为NAT模式 二、信息收集 1、主机发现 用御剑扫描工具扫描虚拟机的NAT网段,发现靶机的IP是192.168.204.141 2、端口扫描 用御剑端口扫描扫描全…...
湖北汽车工业学院-高等数学考纲
湖北汽车工业学院2024年普通专升本考试的《高等数学》考试大纲已经公布。考试形式为闭卷笔试,满分100分,考试时间为90分钟。考试内容主要包括以下几个部分: 1. **函数、极限、连续**: 涉及函数概念、表示法、有界性、周期性、奇偶…...
Linux:Xshell相关配置及前期准备
一、Linux的环境安装 1、裸机安装或者是双系统 2、虚拟机的安装 3、云服务器(推荐)——>安装简单,维护成本低,学习效果好,仿真性高(可多人一起用一个云服务器) 1.1 购买云服务器 使用云服…...
模型 正态分布(通俗解读)
系列文章 分享 模型,了解更多👉 模型_思维模型目录。随机世界的规律,大自然里的钟形曲线。 1 正态分布的应用 1.1 质量管理之六西格玛 六西格玛是一种旨在通过识别和消除缺陷原因来提高制造过程或业务流程质量的管理策略。我们先来了解下六…...
安装了Vue-pdf后,打包文件多出了worker.js和worker.js.gz
解决方式: 修改node_modules/worker-loader/dist/index文件 将 const filename _loaderUtils2.default.interpolateName(this, options.name || 中的 js/[hash].worker.js,更改为 static/js/[hash].worker.js...
使用excel生成国际化多语言js文件的脚本
1、创建一个空文件夹 2、终端 cnpm install xlsx3、在文件夹创建一个index.js // 导入 Node.js 内置的 fs 模块 const fs = require(fs); // 导入 xlsx 模块,用于处理 Excel 文件 const XLSX = require(xlsx);// 读取 Excel 文件 function readExcelFile(filePath) {const …...
【蝉联】摩斯再次获得“中国隐私计算市场份额第一”
蝉联第一 8月2日,全球领先的IT市场研究和咨询公司IDC发布了《中国隐私计算平台厂商市场份额,2023》报告。蚂蚁集团凭借商用隐私计算平台摩斯(MORSE),以 35.3%的市场份额蝉联第一。 2023年,中国隐私计算平台…...
安装 qcloud-python-sts 失败 提示 gbk codecs decode byte 应该如何解决
安装 qcloud-python-sts 失败 提示 gbk codecs decode byte 应该如何解决 解决方案: 将windows 修改为utf-8编码格式 解决步骤如下: 1. 进入控制台 2. 点击区域 4. 点击管理 4.勾选UTF-8 5.重启系统即可...
mv:自动对焦代码
try:# The camera will now focus on whatever is in front of it.sensor.ioctl(sensor.IOCTL_TRIGGER_AUTO_FOCUS) except:raise (Exception("Auto focus is not supported by your sensor/board combination."))...
【C++】数组案例 五只小猪称体重
题目:给出物质小猪体重,找出最大的体重的值并打印 思路:利用菽粟写入五只小猪的体重,让每一个元素都赋值给一个整型变量并每赋值一次就于下一个数组中的元素比,若是大就继续赋值给这个变量,若是小则不赋值…...
Bug 解决 | 后端项目无法正常启动,或依赖服务连接失败
目录 1、版本问题 2、依赖项问题 明明拷贝的代码,为什么别人行,我启动就报错? 这篇文章我就理一下最最常见的项目启动报错的两种原因! 1、版本问题 比如明明项目的 Java 版本是 8,你非得拿 5 跑?那不是…...
Linux: network: mlx5_core crash;dos
https://bugzilla.redhat.com/show_bug.cgi?idCVE-2024-41090 https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id8be915fc5ff9a5e296f6538be12ea75a1a93bdea https://www.openwall.com/lists/oss-security/2024/07/24/4 是tap的驱动向下传递的包…...
用手机剪辑视频素材从哪里找?用手机视频素材库分享
视频编辑是一门充满创意的艺术,无论是制作短片、广告还是个人Vlog,都离不开高质量的视频素材。如果自己拍摄的素材不能完全满足创作需求,或者需要更多样化的内容来丰富视频,那么优质的视频素材来源至关重要。下面推荐几个提供高品…...
挑战杯推荐项目
“人工智能”创意赛 - 智能艺术创作助手:借助大模型技术,开发能根据用户输入的主题、风格等要求,生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用,帮助艺术家和创意爱好者激发创意、提高创作效率。 - 个性化梦境…...
解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八
现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet,点击确认后如下提示 最终上报fail 解决方法 内核升级导致,需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...
【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
Redis数据倾斜问题解决
Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中,部分节点存储的数据量或访问量远高于其他节点,导致这些节点负载过高,影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...
GC1808高性能24位立体声音频ADC芯片解析
1. 芯片概述 GC1808是一款24位立体声音频模数转换器(ADC),支持8kHz~96kHz采样率,集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器,适用于高保真音频采集场景。 2. 核心特性 高精度:24位分辨率,…...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...
C#学习第29天:表达式树(Expression Trees)
目录 什么是表达式树? 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持: 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...
快刀集(1): 一刀斩断视频片头广告
一刀流:用一个简单脚本,秒杀视频片头广告,还你清爽观影体验。 1. 引子 作为一个爱生活、爱学习、爱收藏高清资源的老码农,平时写代码之余看看电影、补补片,是再正常不过的事。 电影嘛,要沉浸,…...
从 GreenPlum 到镜舟数据库:杭银消费金融湖仓一体转型实践
作者:吴岐诗,杭银消费金融大数据应用开发工程师 本文整理自杭银消费金融大数据应用开发工程师在StarRocks Summit Asia 2024的分享 引言:融合数据湖与数仓的创新之路 在数字金融时代,数据已成为金融机构的核心竞争力。杭银消费金…...
【 java 虚拟机知识 第一篇 】
目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…...
