Oracle分区表主键非分区致ORA-14075错误,求设本地分区索引方法
问题:Oracle分区表主键本地索引创建及索引重建报错解决
场景说明
- 多张按
date列分区的Oracle表,示例表字段:id、date、customer_id、code、name、last_name - 主键为
(id,date),customer_id和code字段分别建有独立索引 - 执行的Python程序逻辑:先将表所有索引设为不可用,加载数据后查询当前日期对应的分区,尝试重建该分区的所有索引,代码如下:
def rebuild_index_partition(self,date, table_name): query = "(select partition_name pname from all_tab_partitions where table_name like upper('%{0}%') and " \ "to_date(trim('''' from regexp_substr(extractvalue(dbms_xmlgen.getxmltype('select high_value from all_tab_partitions " \ "where table_name='''||table_name||''' and table_owner = '''||table_owner||''' and partition_name = '''||partition_name||'''')," \ "'//text()'),'''.*?''')),'syyyy-mm-dd hh24:mi:ss')= to_date({1}, 'yyyymmdd', 'nls_calendar=persian') + 1)".format( table_name, date) df = pd.read_sql(query,self.conn) pname = df.loc[0, 'PNAME'] index_query = f'''select distinct a.index_name index_name from all_ind_columns a, all_indexes b where a.index_name=b.index_name and a.table_name = upper('{table_name}') ''' df_index = pd.read_sql(index_query,self.conn) list_index = df_index['INDEX_NAME'].tolist() for i in list_index: rebuild_index = "alter index {0} rebuild partition {1}".format(i, pname) self.execute(rebuild_index) return
报错信息
执行重建索引操作时触发以下错误:
ORA-14075: partition maintenance operations may only be performed on partitioned indices 14075. 00000 - "partition maintenance operations may only be performed on partitioned indices" *Cause: Index named in ALTER INDEX partition maintenance operation is not partitioned, making a partition maintenance operation, at best, meaningless *Action: Ensure that the index named in ALTER INDEX statement specifying a partition maintenance operation is, indeed, partitioned
问题核心
现有主键未设置为分区索引,导致无法针对分区执行索引重建操作,需将主键改为分区本地索引。
解决方案
1. 删除现有主键(若已存在)
ALTER TABLE 你的表名 DROP PRIMARY KEY;
2. 创建分区本地主键索引
由于表按date列分区,且主键包含date列(满足本地索引分区键与表分区键一致的要求),可以创建本地分区主键:
ALTER TABLE 你的表名 ADD CONSTRAINT PK_你的表名 PRIMARY KEY (id, date) USING INDEX LOCAL;
3. 可选:将其他独立索引改为分区本地索引
如果customer_id和code上的索引也需要支持分区级重建,同样改为本地分区索引:
-- 创建customer_id的本地分区索引 CREATE INDEX IDX_你的表名_CUSTOMER_ID ON 你的表名(customer_id) LOCAL; -- 创建code的本地分区索引 CREATE INDEX IDX_你的表名_CODE ON 你的表名(code) LOCAL;
4. 优化Python代码的索引查询逻辑
在查询索引时,只筛选分区索引,避免对非分区索引执行无效操作:
SELECT DISTINCT a.index_name FROM all_ind_columns a JOIN all_indexes b ON a.index_name = b.index_name WHERE a.table_name = UPPER('{table_name}') AND b.partitioned = 'YES'; -- 仅保留分区索引
内容的提问来源于stack exchange,提问作者M_Gh
相关产品推荐
相关产品推荐

