作为一位资深的数据库管理员(DBA),我经常探索如何利用最新的数据库技术来优化性能和提高管理效率。Oracle 12c引入了一个非常有用的新特性——部分索引(Partial Indexes)对于分区表的支持,这为数据库管理和优化提供了新的可能性。
在处理大型数据集时,分区表是一个常见的策略,它通过将数据分割成更小、更易于管理的部分来提高查询性能和维护效率。然而,传统上,当我们对一个分区表创建索引时,该索引会覆盖整个表的所有分区。Oracle 12c中的部分索引功能允许我们只在选定的分区上创建索引,从而实现更加精细化的数据访问控制和性能优化。
在Oracle 12c中,我们可以通过指定每个分区的INDEXING [ON|OFF]子句来决定哪些分区应该被索引。默认情况下,所有分区都是INDEXING ON状态,这意味着它们会被包含在全局或局部索引中。
首先,我们创建一个包含三个分区的表,并分别为前两个分区设置INDEXING ON,最后一个分区设置为INDEXING OFF。
DROP TABLE t1 PURGE;
CREATE TABLE t1 (
id NUMBER,
description VARCHAR2(50),
created_date DATE
)
PARTITION BY RANGE (created_date) (
PARTITION part_2024 VALUES LESS THAN (DATE '2025-01-01'),
PARTITION part_2025 VALUES LESS THAN (DATE '2026-01-01') INDEXING ON,
PARTITION part_2026 VALUES LESS THAN (DATE '2027-01-01') INDEXING OFF
);
接着,我们可以检查这些分区的索引状态:
SELECT table_name, partition_name, indexing
FROM user_tab_partitions
WHERE table_name = 'T1'
ORDER BY partition_position;
TABLE_NAME PARTITION_NAME INDE
------------------------------ ------------------------------ ----
T1 PART_2024 ON
T1 PART_2025 ON
T1 PART_2026 OFF
此查询结果将显示各分区的索引状态,其中只有part_2026分区是INDEXING OFF。
有时,在系统运行期间可能需要根据实际情况动态调整某些分区的索引状态。为此,可以使用ALTER TABLE ... MODIFY PARTITION命令。
ALTER TABLE t1 MODIFY PARTITION part_2024 INDEXING OFF;
ALTER TABLE t1 MODIFY PARTITION part_2025 INDEXING OFF;
ALTER TABLE t1 MODIFY PARTITION part_2026 INDEXING ON;
再次执行上述查询语句以验证更改是否生效。
虽然可以单独控制各个分区的索引状态,默认情况下,索引是INDEXING FULL,即覆盖所有分区。若要创建仅针对特定分区的部分索引,则需明确指定INDEXING PARTIAL。
drop index idx_t1_local_partial;
-- create index idx_t1_local_partial on t1(created_date) local indexing full;
create index idx_t1_local_partial on t1(created_date) local;
在检查USER_IND_PARTITIONS视图中的STATUS列时,我们发现所有索引分区都是可用的。默认情况下,索引创建会忽略表分区的INDEXING设置。
column index_name format a25
select index_name,
partition_name,
status
from user_ind_partitions
where index_name = 'IDX_T1_LOCAL_PARTIAL'
order by 1,2;
INDEX_NAME PARTITION_NAME STATUS
------------------------- ------------------------------ --------
IDX_T1_LOCAL_PARTIAL PART_2024 USABLE
IDX_T1_LOCAL_PARTIAL PART_2025 USABLE
IDX_T1_LOCAL_PARTIAL PART_2026 USABLE
这意味着,无论表分区的INDEXING设置是什么,新创建的索引都将被标记为“usable”,即可以使用。因此,在优化数据库性能时,需要注意这一点,并确保正确地配置表分区的INDEXING设置以满足实际需求。
检查USER_INDEXES视图的INDEXING列,我们看到该索引被标记为FULL索引。
column indexing format a8
select index_name,
indexing
from user_indexes
where index_name = 'T1_LOCAL_PARTIAL_IDX'
order by 1;
INDEX_NAME INDEXING
------------------------- --------
IDX_T1_LOCAL_PARTIAL FULL
SQL>
我们删除索引并重新创建它,这次使用INDEXING PARTIAL子句。
CREATE INDEX idx_t1_created_date ON t1(created_date) LOCAL INDEXING PARTIAL;
这样做的好处在于,只有那些设置了INDEXING ON的分区才会包含在这个索引中,从而减少了不必要的存储开销并提高了查询效率。
检查USER_IND_PARTITIONS视图的状态列,我们看到所有索引分区都是可用的。默认情况下,索引创建忽略了表分区的索引设置。
select index_name,
partition_name,
status
from user_ind_partitions
where index_name = 'IDX_T1_CREATED_DATE'
order by 1,2;
INDEX_NAME PARTITION_NAME STATUS
------------------------- ------------------------------ --------
IDX_T1_CREATED_DATE PART_2024 USABLE
IDX_T1_CREATED_DATE PART_2025 USABLE
IDX_T1_CREATED_DATE PART_2026 UNUSABLE
检查User_Indexes视图的索引列,我们看到索引被标记为PARTIAL索引。
select index_name,
indexing
from user_indexes
where index_name = 'IDX_T1_CREATED_DATE'
order by 1;
INDEX_NAME INDEXING
------------------------- --------
IDX_T1_CREATED_DATE PARTIAL
我们删除索引并重新创建它,这次使用INDEXING PARTIAL子句。
drop index IDX_T1_CREATED_DATE;
create index IDX_T1_LOCAL_CREATED_DATE on t1(created_date) local indexing partial;
现在我们看到标记为INDEXING OFF的表分区未被索引,并且有标记为不可用的索引分区。2026年的表分区被标记为INDEXING ON,因此它已被索引,我们可以看到一个可用的索引分区。
select index_name,
partition_name,
status
from user_ind_partitions
where index_name = 'IDX_T1_LOCAL_CREATED_DATE'
order by 1,2;
INDEX_NAME PARTITION_NAME STATUS
------------------------- ------------------------------ --------
IDX_T1_LOCAL_CREATED_DATE PART_2024 USABLE
IDX_T1_LOCAL_CREATED_DATE PART_2025 USABLE
IDX_T1_LOCAL_CREATED_DATE PART_2026 UNUSABLE
检查USER_INDEXES视图的INDEXING列,我们看到该索引被标记为部分索引。
select index_name,
partition_name,
status
from user_ind_partitions
where index_name = 'IDX_T1_LOCAL_CREATED_DATE'
order by 1,2;
INDEX_NAME INDEXING
------------------------- --------
IDX_T1_LOCAL_CREATED_DATE PARTIAL
全局索引也可以创建为部分索引,其中仅包括标记分区的索引。我们创建一个部分全局索引。请注意使用了索引部分子句。生成的全局索引被标记为“INDEXING PARTIAL”。
create index idx_t1_global_partial on t1(description) global indexing partial;
select index_name,
indexing
from user_indexes
where index_name like 'IDX_T1%'
order by 1;
INDEX_NAME INDEXING
------------------------- --------
IDX_T1_GLOBAL_PARTIAL PARTIAL
IDX_T1_LOCAL_CREATED_DATE PARTIAL
Oracle 12c的部分索引功能极大地增强了我们在处理大规模数据集时的能力,使得我们可以更加灵活地管理索引,优化查询性能。