인덱스 생성시, 컬럼명을 "가공" 또는" 정렬 문구"를 기입하면 오라클이 내부적으로 FUNCTION-BASED INDEX를 생성한다.
그런데 그 이유 때문에, 아래 작업 하다가 애로사항이 발생한다.
1) 테이블의 인덱스와 구성컬럼을 일괄적으로 보고 싶은 경우
2) DBA 또는 튜너가 관리 인덱스테이블과 실제 DB에 생성되어 있는 인덱스의 컬럼간 동일여부
확인하고 싶은 경우
왜냐하면, 가공 컬럼은 인덱스 구성 컬럼 VIEW에서 "SYS_NC0000$" 형태로 나타나기 때문이다.
이를 해결하기 위해서는 "FUNCTION" or "XML" 처리를 하면 된다.
이번 글은 함수를 별도로 만들지 않고 편한 XML 형태이다.
[1] 테스트 테이블 & 인덱스 생성
CREATE TABLE TB_FUNC
(
COL1 VARCHAR2(10)
,COL2 VARCHAR2(20)
,COL3 VARCHAR2(30)
,COL4 VARCHAR2(40)
);
1) 선두 컬럼 COL1에 정렬 문구 기입
CREATE INDEX IX_TB_FUNC_X01 ON TB_FUNC ( COL1 DESC, COL2 );
2) COL2 SUBSTR 가공
CREATE INDEX IX_TB_FUNC_X02 ON TB_FUNC ( SUBSTR(COL2,1,4) );
3) COL3 DECODE 가공
CREATE INDEX IX_TB_FUNC_X03 ON TB_FUNC ( DECODE(COL3,1,4,2,4,5) );
[2] 인덱스 조회
: 인덱스 유형이 FUNCTION-BASED INDEX 이다.
SELECT * FROM DBA_INDEXES WHERE INDEX_NAME LIKE 'IX_TB_FUNC%';

[3] 인덱스 컬럼명 조회
: 가공된 컬럼은 SYS_시작하는 컬럼명으로 표현된다. 이 정보로는 작업 중 인덱스 구성 컬럼 확인시 낭패다.
SELECT A.*
FROM DBA_IND_COLUMNS A
WHERE A.INDEX_OWNER = 'DBADM'
AND A.INDEX_NAME LIKE 'IX_TB_FUNC%' -- 인덱스명
ORDER BY A.INDEX_NAME, A.COLUMN_POSITION ;

[4] 인덱스명 기준으로 컬럼명 가로로 나열하기
: 실제 SYS_로 시작하는 컬럼명의 원본은 DBA_IND_EXPRESSION 뷰에 존재한다.
조인하여 편하게 볼수 있도록 "XML" 로 변환하여 보자
SELECT A.INDEX_OWNER
, A.INDEX_NAME
, LISTAGG( A.COLUMN_NAME_NEW, ',' ) AS COLUMN_LIST
FROM
(
SELECT A.INDEX_OWNER
, A.INDEX_NAME
, A.COLUMN_NAME
, CASE WHEN NOT REGEXP_LIKE( A.COLUMN_NAME ,'^SYS.*\$$', 'i')
THEN A.COLUMN_NAME
ELSE REPLACE(EXTRACTVALUE( DBMS_XMLGEN.GETXMLTYPE( 'SELECT COLUMN_EXPRESSION
FROM DBA_IND_EXPRESSIONS
WHERE INDEX_OWNER = '''|| A.INDEX_OWNER ||'''
AND INDEX_NAME = '''|| A.INDEX_NAME ||'''
AND COLUMN_POSITION = '''|| A.COLUMN_POSITION ||'''' ), '//text()'),'"','')
|| DECODE( A.DESCEND, 'DESC', ' DESC' )
END COLUMN_NAME_NEW
FROM DBA_IND_COLUMNS A
WHERE A.INDEX_OWNER = 'DBADM' -- 소유자
AND A.INDEX_NAME LIKE 'IX_TB_FUNC%' -- 인덱스명
ORDER BY A.INDEX_NAME, A.COLUMN_POSITION
) A
GROUP BY A.INDEX_OWNER, A.INDEX_NAME
ORDER BY A.INDEX_NAME ;

★ 참고 - 인덱스 생성문
CREATE INDEX IX_TB_FUNC_X01 ON TB_FUNC ( COL1 DESC, COL2 );
CREATE INDEX IX_TB_FUNC_X02 ON TB_FUNC ( SUBSTR(COL2,1,4) );
CREATE INDEX IX_TB_FUNC_X03 ON TB_FUNC ( DECODE(COL3,1,4,2,4,5) );
[5] 왜 XMLTYPE으로 변환을 해야 할까?
: DBA_IND_EXPRESSIONS의 "COLUMN_EXPRESSION" 컬럼이 LONG TYPE이기 때문이다.
VARCHAR2 형태와 직접적으로 연결 또는 동일선상에서 작업 처리가 불가능하다.
예를 들면 아래와 같이 NVL 함수로 처리를 한다면 다음과 같은 에러를 만난다.
예시) NVL(B.COLUMN_EXPRESSION, A.COLUMN_NAME))
ORA-00932: inconsitent datatypes: expected LONG got CHAR

'ORACLE > DBA' 카테고리의 다른 글
계정 프로파일 ( PROFILE ) (1) | 2024.11.19 |
---|---|
GLOBAL INDEX가 있는 PARTITION 삭제 or TRUNCATE 방법 (0) | 2024.11.17 |
인덱스 사용 여부 확인 (0) | 2024.10.20 |
프로시져, 함수 AUTHID 이해 (0) | 2024.10.19 |
ORACLE SYSTEM, ROLE, OBJECT 권한 조회 (0) | 2024.10.19 |