인덱스 (INDEX) ?
- 일반 테이블이나 클러스에서 쓰여지는 선택적인 객체로서, 오라클 데이터베이스 테이블내의 원하는 레코드를 빠르게 찾아갈 수 있도록 만들어진 데이터 구조이다.
- SQL 명령문의 처리 속도를 향상시키기 위해서 컬럼에 대해서 생성하는 오라클 객체이다.
- 인덱스는 디스크 I/O를 줄이는 많은 방법 중 하나이다.
-- 인덱스 확인
SELECT * FROM user_indexes;
SELECT * FROM user_indexes WHERE table_name = 'EMP';
SELECT * FROM user_ind_columns WHERE table_name = 'EMP';
PRIMARY KEY, UNIQUE 컬럼은 자동으로 인덱스가 만들어지며 인덱스 이름은 제약조건의이름이다.
-- B-Tree 인덱스 만들기
SELECT empNo, name, sal FROM emp WHERE name = '심심해';
실행하려는 SQL의 범위를 잡고 F10을 누르면 밑에 계획 설명을 보여준다. COST를 보면 SQL문을 실행해서 걸리는 여러 요인들을 계산해서 대략적인 수치를 보여준다. (원래는 3인데, 지금은 INDEX를 만들어 놓은 상태라서 2입니다.)
-- B-Tree 인덱스 작성
CREATE INDEX idx_emp_name ON emp ( name ); -- NON UNIQUE
이름은 중복의 값이 있을 수 있기 때문에 UNIQUE 값이 아닙니다.
CREATE INDEX 인덱스명 ON 테이블명 (컬럼) ;
여러 예들 ;
SELECT empNo, name, sal FROM emp WHERE SUBSTR(name, 1, 1) = '심';
SELECT empNo, name, sal FROM emp WHERE NOT name = '심심해';
위의 쿼리의 경우 인덱스를 사용하지 않습니다. 비교전에 SUBSTR를 통해 변형되기 때문입니다. 또 NOT을 사용한 문장에서도 인덱스가 사용되지 않습니다.
-- 인덱스 삭제
DROP INDEX idx_emp_name;
DROP INDEX 인덱스명; 을 통해 삭제할 수 있습니다.
-- 결합 인덱스
CREATE INDEX idx_emp_comp ON emp(name, dept);
AND 조건으로 검색하는 경우 결합 인덱스를 만들면 성능에 중요한 역할을 합니다. OR연산은 인덱스를 만들지 않습니다.
CREATE INDEX 인덱스명 ON 테이블명(컬럼명, 컬럼명);
※ 주의
CREATE INDEX idx_emp_comp ON emp(dept, name);
위 쿼리처럼 INDEX를 만들면 dept 에서 name 을 검색하므로, (순서가 다르므로) name을 검색하고 dept을 검색하는 것보다 속도가 느립니다. name을 만족하는 행보다 dept을 만족하는 행이 더 많기 때문입니다. (name이 중복값이 있을 수 있지만 dept보다 행의 개수가 적다.) 따라서 결합 인덱스를 만들 때, 괄호 안의 위치도 신경을 써야합니다.
-- 함수 기반 인덱스 만들기
CREATE INDEX idx_emp_fun ON emp(MOD(SUBSTR(rrn, 8, 1), 2 ) ) ;
-- 인덱스 관리
-- 모니터링
-- 인덱스 생성
CREATE INDEX idx_emp_name ON emp(name);
-- 모니터링 시작
ALTER INDEX idx_emp_name MONITORING USAGE;
-- 인덱스 사용 유무 확인
SELECT * FROM v$object_usage; -- used : no
-- 모니터링 중단
ALTER INDEX idx_emp_name NOMONITORING USAGE;
-- REBUILD
실습을 위해 테이블을 작성하고 테이터를 10000개를 넣어주었습니다.
CREATE TABLE demo (
num NUMBER
);
BEGIN
FOR n IN 1 .. 10000 LOOP
INSERT INTO demo VALUES (n);
END LOOP;
COMMIT;
END;
/
SELECT COUNT(*) FROM demo;
-- 위 테이블에 인덱스 추가하기.
CREATE INDEX idx_demo_num ON demo(num);
-- 인덱스 분석
ANALYZE INDEX idx_demo_num VALIDATE STRUCTURE;
SELECT * FROM index_stats;
SELECT (del_lf_rows_len / lf_rows_len ) * 100
FROM index_stats
WHERE name = 'IDX_DEMO_NUM'; -- 0에 가까우면 좋은 상태(인덱스가 깨지지 않은 상태)
DELETE FROM demo WHERE num <= 4000;
COMMIT;
ANALYZE INDEX idx_demo_num VALIDATE STRUCTURE;
SELECT (del_lf_rows_len / lf_rows_len ) * 100
FROM index_stats
WHERE name = 'IDX_DEMO_NUM'; -- 40% 정도 밸런싱이 깨짐
세 번째 쿼리를 처음 실행하면 0이 나오는데, 이는 인덱스가 깨지지 않은 상태를 의미합니다. 후 에, 10000개의 데이터에서 4000개를 삭제하면 IDX_DEMO_NUM 이 39.xxxxx 로 나옵니다. 인덱스가 40%정도 깨져있는 것을 확인할 수 있습니다.
-- REBUILD
ALTER INDEX idx_demo_num REBUILD; -- 밸런싱에 문제가 있으면 관리자가 다시 조절한다.
-- 인덱스 다시 분석
ANALYZE INDEX idx_demo_num VALIDATE STRUCTURE;
SELECT (del_lf_rows_len / lf_rows_len ) * 100
FROM index_stats
WHERE name = 'IDX_DEMO_NUM' -- 인덱스를 REBUILD 했기 때문에 다시 밸런싱이 좋아짐.
밸런싱에 문제가 있어서 ALTE INDEX 인덱스명 REBUILD; 를 통해 REBUILD하고 나면 다시 0으로 되어있는 것을 확인할 수 있습니다.
인덱스는 데이터가 삭제되도 남아있기 때문에 밸런싱이 깨지면 나중에 REBUILD를 하는 것이 필요해보입니다.
'쌍용강북교육센터 > 8월' 카테고리의 다른 글
0820_Oracle[PL/SQL] : TRIGGER 트리거 (0) | 2021.08.23 |
---|---|
0820_Oracle[PL/SQL] : PACKAGE 패키지 (0) | 2021.08.23 |
0819_Oracle[PL/SQL] : PROCEDURE, FUNCTION 예제 (2) | 2021.08.20 |
0818_Oracle : IDENTITY COLUMN (2) | 2021.08.19 |
0818_Oracle : INVISIBLE, VISIBLE COLUMN (1) | 2021.08.19 |