我已经编写了一段SQL脚本来将表空间中的所有索引移动到其他索引,代码正常并且工作正常。但是我对分区索引感到困惑,为什么它们中的一些在DBA_SEGMENTS中并且其中一些在DBA_IND_PARTITIONS中,为什么那些在DBA_IND_PARTITIONS内部不在DBA_SEGMENTS内。
有人可以解释这些表在Oracle中的区别和用法
这是我将索引从一个表空间移动到其他
的脚本DECLARE
-- SETTING
SOURCE_TS VARCHAR2(30) := 'source_tablespace'; -- SOURCE TABLESPACE
DEST_TS VARCHAR2(30) := 'destination_tablespace'; --DESCTINATION TABLESPACE
-- SHOULD_DROPINDEX BOOLEAN := FALSE;
----------------------------------------------
TOP NUMBER := 2;
COUNTER NUMBER := 0;
SHOULD_MOVEINDEX BOOLEAN := TRUE;
PARALLEL_DEGREE NUMBER := 4;
ENABLE_PARALLEL BOOLEAN := TRUE;
INDEX_NAMES_TO_SCAPE VARCHAR2(1000) := '';
----------------------------------------------
-- VARIABLES
SQLCMD VARCHAR2(1000);
STARTTIME NUMBER;
BEGIN
STARTTIME := DBMS_UTILITY.GET_TIME();
DBMS_OUTPUT.PUT_LINE('STARTING TIME : ' ||
TO_CHAR(SYSDATE, 'YYYY/MM/DD HH24:MI:SS'));
DBMS_OUTPUT.PUT_LINE('----------------------------------------------------');
FOR IDXS IN (SELECT OWNER || '.' || INDEX_NAME FN,
INDEX_NAME IDN,
INDEX_TYPE IDT,
PARTITIONED,
(CASE
WHEN UNIQUENESS = 'UNIQUE' THEN
'Y'
ELSE
'N'
END) ISUNIQUE,
OWNER
FROM DBA_INDEXES
WHERE (TABLESPACE_NAME = SOURCE_TS OR
INDEX_NAME IN
(SELECT DISTINCT SEGMENT_NAME
FROM DBA_SEGMENTS
WHERE TABLESPACE_NAME = SOURCE_TS) OR
INDEX_NAME IN
(SELECT DISTINCT INDEX_NAME
FROM DBA_IND_PARTITIONS
WHERE TABLESPACE_NAME = SOURCE_TS))
ORDER BY OWNER ASC, INDEX_NAME ASC
) LOOP
IF COUNTER >= TOP THEN
DBMS_OUTPUT.PUT_LINE('EXIT ON COUNTER EXCEED');
EXIT;
END IF;
IF INSTR(INDEX_NAMES_TO_SCAPE, IDXS.IDN) >= 1 THEN
CONTINUE;
END IF;
IF IDXS.PARTITIONED = 'YES' THEN
FOR PIDX IN (SELECT *
FROM DBA_IND_PARTITIONS
WHERE INDEX_OWNER = IDXS.OWNER
AND INDEX_NAME = IDXS.IDN
AND TABLESPACE_NAME = SOURCE_TS) LOOP
-- ** EXECUTE LOCAL (PARTITIONED) INDEX REBUILD COMMAND **
SQLCMD := 'ALTER INDEX ' || IDXS.FN || ' REBUILD PARTITION ' ||
PIDX.PARTITION_NAME || ' TABLESPACE ' || DEST_TS;
IF ENABLE_PARALLEL = TRUE THEN
SQLCMD := SQLCMD || ' PARALLEL ' || PARALLEL_DEGREE;
END IF;
--SQLCMD := SQLCMD || ' NONLOGGING ';
DBMS_OUTPUT.PUT_LINE(SQLCMD);
EXECUTE IMMEDIATE SQLCMD;
END LOOP;
IF ENABLE_PARALLEL = TRUE THEN
SQLCMD := 'ALTER INDEX ' || IDXS.FN || ' NOPARALLEL ';
DBMS_OUTPUT.PUT_LINE(SQLCMD);
EXECUTE IMMEDIATE SQLCMD;
END IF;
ELSE
-- ** EXECUTE INDEX REBUILD COMMAND **
SQLCMD := 'ALTER INDEX ' || IDXS.FN || ' REBUILD TABLESPACE ' ||
DEST_TS;
IF ENABLE_PARALLEL = TRUE THEN
SQLCMD := SQLCMD || ' PARALLEL ' || PARALLEL_DEGREE;
END IF;
--SQLCMD := SQLCMD || ' NONLOGGING ';
DBMS_OUTPUT.PUT_LINE(SQLCMD);
EXECUTE IMMEDIATE SQLCMD;
IF ENABLE_PARALLEL = TRUE THEN
SQLCMD := 'ALTER INDEX ' || IDXS.FN || ' NOPARALLEL ';
DBMS_OUTPUT.PUT_LINE(SQLCMD);
EXECUTE IMMEDIATE SQLCMD;
END IF;
END IF;
COUNTER := COUNTER + 1;
DBMS_OUTPUT.PUT_LINE('#');
END LOOP;
DBMS_OUTPUT.PUT_LINE('----------------------------------------------------');
DBMS_OUTPUT.PUT_LINE('END TIME : ' ||
TO_CHAR(SYSDATE, 'YYYY/MM/DD HH24:MI:SS'));
DBMS_OUTPUT.PUT_LINE('DURATION: ' ||
TO_CHAR(DBMS_UTILITY.GET_TIME() - STARTTIME) ||
' MS.');
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('ERR MSG: ' || SQLERRM || ', CODE: ' || SQLCODE);
END;