Leeyebin의 블로그

[2017.03.27~2017.03.30]데이터베이스 분석 및 개선을 통한 성능 확보 교육 3/4 본문

외부/교육

[2017.03.27~2017.03.30]데이터베이스 분석 및 개선을 통한 성능 확보 교육 3/4

안되면될때까지 2017. 3. 30. 00:13


8. 인덱스 검색 방법


8.1 INDEX 설계 시 주의사항

-조건을 만족하는 데이터의 분포도가 10% 내외일 때(분포도 = (조건을 만족하는 행수 / 전체행수) * 100)

-대용량 데이터를 가진 테이블에 적용했을 때

-분포도가 나쁘더라도 FAST INDEX SCAN이 가능한 경우(분포가 나빠도 적극적으로 사용해보고 판단해보자)

-다양한 인덱스 유형 중에 가장 적합한 인덱스를 선택

-테이블스페이스와 물리적 크기 설계 고려

-좋은 분포도를 가진다


8.2 INDEX의 종류

Balance*Tree

이미지 출처 : http://docs.oracle.com/cd/E25054_01/server.1111/e25789/indexiot.htm

참고 B Tree 알고리즘 애니메이션 : http://ats.oka.nu/b-tree/b-tree.html


-일반적으로 개발자들이 생성하는 인덱스의 대부분이 밸런스트리 인덱스, 인덱스의 좌와 우가 대칭구조를 이루고 있다.

가장 중간 값을 ROOT-LEVEL의 블록에 저장한다. 그리고 BRANCH-LEVEL에는 중간 값을 기준으로 작은 값, 큰 값에 대한 정보를 각각 좌우에 저장한다. LEAF-LEVEL 블록에는 해당 테이블의 컬럼정보와 ROWID 정보를 함께 저장한다.


B*TREE 인덱스의 합병(ALTER INDEX [index_name] COALESCE;)

-인덱스 키 값을 재 배치

-불필요한 블록의 검색을 방지

-공간의 낭비를 방지

-인덱스를 이용한 검색 성능 향상


8.2.2 Reverse Index

8.2.3 Descending Index

8.2.4 Function-Based Index

8.2.5 Index Organization Index

8.2.6 BITMAP Index



P384 인덱스의 밸런스 분석 SQL> CREATE TABLE BIG_EMP1 AS SELECT * FROM BIG_EMP; 테이블이 생성되었습니다. SQL> CREATE INDEX I_BIGEMP_EMPNO ON BIG_EMP1(EMPNO); 인덱스가 생성되었습니다. SQL> ANALYZE INDEX I_BIGEMP_EMPNO VALIDATE STRUCTURE; 인덱스가 분석되었습니다. SQL> SELECT (DEL_LF_ROWS_LEN / LF_ROWS_LEN) * 100 AS BALANCING   2  FROM INDEX_STATS;  BALANCING ----------          0 --인덱스의 밸런스 정도

P384 데이터 삭제로 밸런스 깨기 최초 인덱스가 구성되면 완벽한 밸런싱을 유지하지만 반복되는 Delete, Insert작업으로 인해 밸런싱은 깨진다. SQL> DELETE FROM BIG_EMP1 WHERE EMPNO > 1 AND EMPNO < 25000; 23958 행이 삭제되었습니다. SQL> ANALYZE INDEX I_BIGEMP_EMPNO VALIDATE STRUCTURE; 인덱스가 분석되었습니다. SQL> SELECT (DEL_LF_ROWS_LEN / LF_ROWS_LEN) * 100 AS BALANCING   2  FROM INDEX_STATS;  BALANCING ---------- 82.3819436 --인덱스의 밸런스 정도

P385 리빌드(인덱스의 재구성)
일반적으로 인덱스 밸런싱이 20%를 초과하게 되면 성능이 저하된다고 한다.(Depth는 3level)
SQL> ALTER INDEX I_BIGEMP_EMPNO REBUILD NOLOGGING;

인덱스가 변경되었습니다.

SQL> ANALYZE INDEX I_BIGEMP_EMPNO VALIDATE STRUCTURE;

인덱스가 분석되었습니다.

SQL> SELECT (DEL_LF_ROWS_LEN / LF_ROWS_LEN) * 100 AS BALANCING
  2  FROM INDEX_STATS;

 BALANCING
----------
         0

P81

Tablespace의 단편화 현상

테이블스페이스의 COALESCE

P81 테이블스페이스 단편화 현상 분석
SQL> SELECT TABLESPACE_NAME, TOTAL_EXTENTS, PERCENT_EXTENTS_COALESCED
  2  FROM DBA_FREE_SPACE_COALESCED
  3  --WHERE PERCENT_EXTENTS_COALESCED <> 100;--원래 단편화 현상에 대한 결과가 나오는데 테스트DB라 주석처리해둠(100은 단편화안되어있다는 뜻)

TABLESPACE_NAME                TOTAL_EXTENTS PERCENT_EXTENTS_COALESCED
------------------------------ ------------- -------------------------
SYSAUX                                     1                       100
EXAMPLE                                    3                       100
UNDOTBS1                                  34                       100
USERS                                      2                       100
SYSTEM                                     2                       100

선택된 레코드가 없습니다.
테이블스페이스 빈 공간들을 하나의 공간으로 합병 시키는 명령(2회에서 3회 진행, 100 될 때까지)
SQL> ALTER TABLESPACE EXAMPLE COALESCE;

테이블스페이스가 변경되었습니다.

SQL> SELECT TABLESPACE_NAME, TOTAL_EXTENTS, PERCENT_EXTENTS_COALESCED
  2  FROM DBA_FREE_SPACE_COALESCED
  3  WHERE PERCENT_EXTENTS_COALESCED <> 100;

선택된 레코드가 없습니다.


P.S

C:\app\KODB\product\11.2.0\dbhome_1\sqlplus\admin\glogin.sql(미리 쳐놓고 싶은거 입력하기, SET LINESIZE 300 , SET LINESIZE 100등 SET TRACE 등)



P360

파일 tkprof.sql 필요

c:\app\kodb\diag\rdbms\orcl\orcl\trace



인덱스는 논리적 인덱스/물리적 인덱스


P358

8.3 싱글 컬럼 인덱스와 결합 컬럼 인덱스의 검색방법

8.3.1 싱글 컬럼 인덱스의 실행 경로(하나의 컬럼으로 만들어지는 인덱스)

SELECT * FROM BIG_EMP
WHERE DEPTNO = 10 AND JOB = 'CLERK'

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      1      0.00       0.00          0          0          0           0
Fetch       78      0.01       0.00          0        261          0        1154
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total       80      0.01       0.00          0        261          0        1154

Misses in library cache during parse: 1
Optimizer mode: RULE
Parsing user id: 91  

Rows     Row Source Operation
-------  ---------------------------------------------------
   1154  TABLE ACCESS FULL BIG_EMP (cr=261 pr=0 pw=0 time=7814 us)

8.3.2 결합 컬럼 인덱스의 실행 경로(2개 이상의 컬럼으로 만들어지는 인덱스)

결합 인덱스의 작성지침

1) 단지 하나의 테이블에서 컬럼 들을 참조해야함

2)최대 16개 컬럼으로 생성할 수 있음

3)결합 인덱스의 전체 컬럼 길이는 DB_BLOCK_SIZE 파라미터의 값의 1/2을 초과하면 안됨

4)결합 인덱스를 생성할 때는 가장 적은 데이터를 가진 컬럼을 선행 컬럼으로 결정하는게 유리

5)선행 컬럼으로 결정하기 힘든 경우에는 자주 사용되는 컬럼을 선행 컬럼으로 결정

6)결합 인덱스 수가 많으면 많을수록 데이터의 검색 속도는 향상될 수 있지만 오히려 DML문을 수행하는 성능은 저하되기 때문에 적절한 개수를 유지하는 것이 유리함.

SELECT * FROM BIG_EMP
WHERE DEPTNO = 10 AND JOB = 'CLERK'

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      1      0.00       0.00          0          0          0           0
Fetch       78      0.00       0.00         12        288          0        1154
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total       80      0.00       0.00         12        288          0        1154

Misses in library cache during parse: 1
Optimizer mode: RULE
Parsing user id: 91  

Rows     Row Source Operation
-------  ---------------------------------------------------
   1154  TABLE ACCESS BY INDEX ROWID BIG_EMP (cr=288 pr=12 pw=0 time=5893 us)
   1154   INDEX RANGE SCAN I_EMP_DEPTNO_JOB (cr=82 pr=12 pw=0 time=5188 us)(object id 74638)


P.S

*Index 생성 시점

1)table 생성시(pk, unq)

2)필요에 따라


A가 인덱스컬럼일때 인덱스를 사용하는가

WHERE A = 1 (O)

WHERE A = 1 AND C = 3 (O)

WHERE B = 2 AND C = 3 (X 혹은 세모(9i버전부터 Index skip scan으로 가능은하다.))


8.3.3 결합 컬럼 인덱스의 선행 컬럼 우선 순위

#################################HIREDATE, DEPTNO 순

SQL> ALTER SESSION SET OPTIMIZER_MODE=RULE;

세션이 변경되었습니다.

SQL> ALTER SESSION SET SQL_TRACE=TRUE;

세션이 변경되었습니다.

SQL> CREATE INDEX I_EMP_DATA_DEPTNO ON BIG_EMP(HIREDATE, DEPTNO);

인덱스가 생성되었습니다.

SQL> SELECT DEPTNO, COUNT(*), SUM(SAL)
  2  FROM BIG_EMP
  3  WHERE HIREDATE BETWEEN TO_DATE('1983-01-01', 'YYYY-MM-DD')
  4     AND TO_DATE('1984-12-31', 'YYYY-MM-DD')
  5     AND (DEPTNO = 70 OR DEPTNO = 80 OR DEPTNO = 90)
  6  GROUP BY DEPTNO
  7  ORDER BY SUM(SAL) DESC;

    DEPTNO   COUNT(*)   SUM(SAL)
---------- ---------- ----------
        80         50     105825
        90         53    92158.5
        70         28    53084.5

SQL> @TKPROF.SQL
********************************************************************************

SELECT DEPTNO, COUNT(*), SUM(SAL)
FROM BIG_EMP
WHERE HIREDATE BETWEEN TO_DATE('1983-01-01', 'YYYY-MM-DD')
	AND TO_DATE('1984-12-31', 'YYYY-MM-DD')
	AND (DEPTNO = 70 OR DEPTNO = 80 OR DEPTNO = 90)
GROUP BY DEPTNO
ORDER BY SUM(SAL) DESC

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      1      0.00       0.00          0          0          0           0
Fetch        2      0.03       0.05         87       7993          0           3
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        4      0.03       0.05         87       7993          0           3

Misses in library cache during parse: 1
Optimizer mode: RULE
Parsing user id: 91  

Rows     Row Source Operation
-------  ---------------------------------------------------
      3  SORT ORDER BY (cr=7993 pr=87 pw=0 time=0 us cost=0 size=0 card=0)
      3   SORT GROUP BY (cr=7993 pr=87 pw=0 time=2 us)
    131    TABLE ACCESS BY INDEX ROWID BIG_EMP (cr=7993 pr=87 pw=0 time=260 us)
  28281     INDEX RANGE SCAN I_EMP_DATA_DEPTNO (cr=88 pr=87 pw=0 time=34422 us)(object id 74639)
#################################DEPTNO, HIREDATE 순(결합 인덱스의 컬럼 순서를 바꾼 것 만으로 불필요한 검색범위를 줄일 수 있다.)

SQL> ALTER SESSION SET OPTIMIZER_MODE=RULE;

세션이 변경되었습니다.

SQL> ALTER SESSION SET SQL_TRACE=TRUE;

세션이 변경되었습니다.

SQL> CREATE INDEX I_EMP_DEPTNO_DATE ON BIG_EMP(DEPTNO, HIREDATE);

인덱스가 생성되었습니다.

SQL>
SQL> SELECT DEPTNO, COUNT(*), SUM(SAL)
  2  FROM BIG_EMP
  3  WHERE HIREDATE BETWEEN TO_DATE('1983-01-01', 'YYYY-MM-DD')
  4     AND TO_DATE('1984-12-31', 'YYYY-MM-DD')
  5     AND (DEPTNO = 70 OR DEPTNO = 80 OR DEPTNO = 90)
  6  GROUP BY DEPTNO
  7  ORDER BY SUM(SAL) DESC
  8  ;

    DEPTNO   COUNT(*)   SUM(SAL)
---------- ---------- ----------
        80         50     105825
        90         53    92158.5
        70         28    53084.5

SELECT DEPTNO, COUNT(*), SUM(SAL)
FROM BIG_EMP
WHERE HIREDATE BETWEEN TO_DATE('1983-01-01', 'YYYY-MM-DD')
	AND TO_DATE('1984-12-31', 'YYYY-MM-DD')
	AND (DEPTNO = 70 OR DEPTNO = 80 OR DEPTNO = 90)
GROUP BY DEPTNO
ORDER BY SUM(SAL) DESC

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      1      0.00       0.00          0          0          0           0
Fetch        2      0.00       0.01         15        138          0           3
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        4      0.00       0.01         15        138          0           3

Misses in library cache during parse: 1
Optimizer mode: RULE
Parsing user id: 91  

Rows     Row Source Operation
-------  ---------------------------------------------------
      3  SORT ORDER BY (cr=138 pr=15 pw=0 time=0 us cost=0 size=0 card=0)
      3   SORT GROUP BY (cr=138 pr=15 pw=0 time=2 us)
    131    CONCATENATION  (cr=138 pr=15 pw=0 time=390 us)
     53     TABLE ACCESS BY INDEX ROWID BIG_EMP (cr=56 pr=15 pw=0 time=260 us)
     53      INDEX RANGE SCAN I_EMP_DEPTNO_DATE (cr=3 pr=15 pw=0 time=52 us)(object id 74640)
     50     TABLE ACCESS BY INDEX ROWID BIG_EMP (cr=52 pr=0 pw=0 time=98 us)
     50      INDEX RANGE SCAN I_EMP_DEPTNO_DATE (cr=2 pr=0 pw=0 time=0 us)(object id 74640)
     28     TABLE ACCESS BY INDEX ROWID BIG_EMP (cr=30 pr=0 pw=0 time=54 us)
     28      INDEX RANGE SCAN I_EMP_DEPTNO_DATE (cr=2 pr=0 pw=0 time=27 us)(object id 74640)

#################################DEPTNO, HIREDATE, SAL 순(WHERE 조건절이 없는 컬럼이더라도 필요에 따라 결합컬럼 인덱스로 생성될 수 있다.) SQL> ALTER SESSION SET OPTIMIZER_MODE=RULE; 세션이 변경되었습니다. SQL> ALTER SESSION SET SQL_TRACE=TRUE; 세션이 변경되었습니다. SQL> CREATE INDEX I_EMP_DEPTNO_DATE ON BIG_EMP(DEPTNO, HIREDATE); 인덱스가 생성되었습니다. SQL> SQL> SELECT DEPTNO, COUNT(*), SUM(SAL)   2  FROM BIG_EMP   3  WHERE HIREDATE BETWEEN TO_DATE('1983-01-01', 'YYYY-MM-DD')   4     AND TO_DATE('1984-12-31', 'YYYY-MM-DD')   5     AND (DEPTNO = 70 OR DEPTNO = 80 OR DEPTNO = 90)   6  GROUP BY DEPTNO   7  ORDER BY SUM(SAL) DESC   8  ;     DEPTNO   COUNT(*)   SUM(SAL) ---------- ---------- ----------         80         50     105825         90         53    92158.5         70         28    53084.5 SELECT DEPTNO, COUNT(*), SUM(SAL) FROM BIG_EMP WHERE HIREDATE BETWEEN TO_DATE('1983-01-01', 'YYYY-MM-DD')    AND TO_DATE('1984-12-31', 'YYYY-MM-DD')    AND (DEPTNO = 70 OR DEPTNO = 80 OR DEPTNO = 90) GROUP BY DEPTNO ORDER BY SUM(SAL) DESC call     count       cpu    elapsed       disk      query    current        rows ------- ------  -------- ---------- ---------- ---------- ----------  ---------- Parse        1      0.00       0.00          0          0          0           0 Execute      1      0.00       0.00          0          0          0           0 Fetch        2      0.00       0.02         15          6          0           3 ------- ------  -------- ---------- ---------- ---------- ----------  ---------- total        4      0.00       0.02         15          6          0           3 Misses in library cache during parse: 1 Optimizer mode: RULE Parsing user id: 91   Rows     Row Source Operation -------  ---------------------------------------------------       3  SORT ORDER BY (cr=6 pr=15 pw=0 time=0 us cost=0 size=0 card=0)       3   SORT GROUP BY (cr=6 pr=15 pw=0 time=2 us)     131    CONCATENATION  (cr=6 pr=15 pw=0 time=130 us)      53     INDEX RANGE SCAN I_EMP_DEPTNO_DATE (cr=2 pr=7 pw=0 time=52 us)(object id 74641)      50     INDEX RANGE SCAN I_EMP_DEPTNO_DATE (cr=2 pr=1 pw=0 time=0 us)(object id 74641)      28     INDEX RANGE SCAN I_EMP_DEPTNO_DATE (cr=2 pr=7 pw=0 time=0 us)(object id 74641)

8.3.4 선행 컬럼 결정하는 기준

-WHERE절에서 자주 검색되는 컴럼이 선행 컬럼이 되어야함

-분포도가 좋은 컬럼이 선행 컬럼이 되어야함

-데이터양이 적은 컬럼을 선행으로 사용해야함

-BETWEENM > AND <, LIKE 연산자로 검색되지 않는 컬럼을 선행 컬럼으로 사용해야함.

-비즈니스룰적으로도 생각해봐야함



P377

8.4 인덱스를 사용하지 못하는경우

1)인덱스가 있는 컬럼을 표현식 또는 함수로 변형을 시키면 인덱스를 사용할 수 없다.(해결책은 DNAME사용 혹은 Function Based Index만들기)

2)!=(부정 연산자)를 사용하면 인덱스를 사용할 수 없다.

3)IS NULL을 사용하면 인덱스를 사용할 수 없다.(인덱스에는 NULL값은 포함되지 않기 때문에 IS NULL의 의미는 인덱스를 사용할 수 없다.)

4)와일드카드(%)로 시작하는 LIKE문은 사용할 수 없다.(검색해야할 범위를 알 수 없기 때문에 Full Table Scan이 더 빠른 검색을 해준다고 오라클서버가 판단함, 단 와일드 카드(%)로 끝나는 검색조건에는 인덱스가 사용됨)

5)인덱스가 생성되어 있는 컬럼을 함수를 이용하여 조작하게 되면 인덱스를 사용할 수 없다.


1)사례

******************************************************************************** SQL> ALTER SESSION SET OPTIMIZER_MODE=RULE; 세션이 변경되었습니다. SQL> SET AUTOTRACE TRACE; SQL> CREATE INDEX I_DEPT_DNAME ON DEPT(DNAME); 인덱스가 생성되었습니다. SQL> SELECT *   2  FROM DEPT   3  WHERE SUBSTR(DNAME, 1, 3) = 'ABC'; 선택된 레코드가 없습니다. Execution Plan ---------------------------------------------------------- ---------------------------------- | Id  | Operation         | Name | ---------------------------------- |   0 | SELECT STATEMENT  |      | |*  1 |  TABLE ACCESS FULL| DEPT | --Full Table Scan ---------------------------------- ******************************************************************************** 해결 SQL> SELECT *   2  FROM DEPT   3  WHERE DNAME LIKE 'ABC%'; 선택된 레코드가 없습니다. Execution Plan ---------------------------------------------------------- ---------------------------------------------------- | Id  | Operation                   | Name         | ---------------------------------------------------- |   0 | SELECT STATEMENT            |              | |   1 |  TABLE ACCESS BY INDEX ROWID| DEPT         | |*  2 |   INDEX RANGE SCAN          | I_DEPT_DNAME | ---------------------------------------------------- ********************************************************************************

2)사례

********************************************************************************
SQL> CREATE INDEX I_EMP_JOB ON EMP(JOB);

인덱스가 생성되었습니다.

SQL> SELECT *
  2  FROM EMP
  3  WHERE JOB <> 'SALESMAN';

10 개의 행이 선택되었습니다.


Execution Plan
----------------------------------------------------------

----------------------------------
| Id  | Operation         | Name |
----------------------------------
|   0 | SELECT STATEMENT  |      |
|*  1 |  TABLE ACCESS FULL| EMP  |
----------------------------------
********************************************************************************
해결(하지만 좋은 성능을 기대할 수 있는 쿼리는 아니며 인덱스를 사용할 수 있는 하나의 경우임)
SQL> SELECT *
  2  FROM EMP A
  3  WHERE NOT EXISTS ( SELECT ' '
  4                     FROM EMP B
  5                     WHERE (A.ENAME = B.ENAME)
  6  AND (B.JOB = 'SALESMAN'));

10 개의 행이 선택되었습니다.


Execution Plan
----------------------------------------------------------

--------------------------------------------------
| Id  | Operation                    | Name      |
--------------------------------------------------
|   0 | SELECT STATEMENT             |           |
|*  1 |  FILTER                      |           |
|   2 |   TABLE ACCESS FULL          | EMP       |
|*  3 |   TABLE ACCESS BY INDEX ROWID| EMP       |
|*  4 |    INDEX RANGE SCAN          | I_EMP_JOB |
--------------------------------------------------
********************************************************************************

3)사례

********************************************************************************
SQL> CREATE INDEX I_EMP_ENAME ON EMP(ENAME);

인덱스가 생성되었습니다.
SQL> SELECT *
  2  FROM EMP
  3  WHERE ENAME IS NOT NULL;

14 개의 행이 선택되었습니다.


Execution Plan
----------------------------------------------------------

----------------------------------
| Id  | Operation         | Name |
----------------------------------
|   0 | SELECT STATEMENT  |      |
|*  1 |  TABLE ACCESS FULL| EMP  |
----------------------------------
********************************************************************************
해결
SQL> SELECT *
  2  FROM EMP WHERE ENAME > ' ';

14 개의 행이 선택되었습니다.


Execution Plan
----------------------------------------------------------

---------------------------------------------------
| Id  | Operation                   | Name        |
---------------------------------------------------
|   0 | SELECT STATEMENT            |             |
|   1 |  TABLE ACCESS BY INDEX ROWID| EMP         |
|*  2 |   INDEX RANGE SCAN          | I_EMP_ENAME |
---------------------------------------------------
********************************************************************************

4)사례

********************************************************************************
SQL> DROP INDEX I_EMP_ENAME;

인덱스가 삭제되었습니다.

SQL> CREATE INDEX I_EMP_JOB ON EMP(JOB);

인덱스가 생성되었습니다.

SQL> SELECT *
  2  FROM EMP
  3  WHERE JOB LIKE '%AB';

선택된 레코드가 없습니다.


Execution Plan
----------------------------------------------------------

----------------------------------
| Id  | Operation         | Name |
----------------------------------
|   0 | SELECT STATEMENT  |      |
|*  1 |  TABLE ACCESS FULL| EMP  |
----------------------------------
********************************************************************************
해결 ㄴㄴ해
********************************************************************************

5)사례

******************************************************************************** SQL> CREATE INDEX I_EMP_SAL ON EMP(SAL); 인덱스가 생성되었습니다. SQL> SELECT *   2  FROM EMP   3  WHERE NVL(SAL, 0) < 4000; 13 개의 행이 선택되었습니다. Execution Plan ---------------------------------------------------------- ---------------------------------- | Id  | Operation         | Name | ---------------------------------- |   0 | SELECT STATEMENT  |      | |*  1 |  TABLE ACCESS FULL| EMP  | --Full Table Scan ---------------------------------- ******************************************************************************** 해결 SQL> ALTER SESSION SET OPTIMIZER_MODE=CHOOSE; 세션이 변경되었습니다. SQL> CREATE INDEX I_EMP_SAL_NVL ON EMP(NVL(SAL, 0)); 인덱스가 생성되었습니다. SQL> ANALYZE TABLE EMP COMPUTE STATISTICS; 테이블이 분석되었습니다. SQL> SELECT *   2  FROM EMP   3  WHERE (NVL(SAL, 0)) < 4000; --Function Based Index(함수기반 인덱스 생성) 13 개의 행이 선택되었습니다. Execution Plan ---------------------------------------------------------- --------------------------------------------------------------- | Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| --------------------------------------------------------------- |   0 | SELECT STATEMENT  |      |    11 |   385 |     2   (0)| |*  1 |  TABLE ACCESS FULL| EMP  |    11 |   385 |     2   (0)| --------------------------------------------------------------- ********************************************************************************


P.S

*Full Table Scan을 위한 성능 개선 방법

1)db_file_multiblock_read_count(Full Scan(Full Table Scan, Index Fast Full Scan) 수행 시 한번에 읽어 들일 Block 수를 결정한다. Full Scan의 성능을 제어하는 목적으로 사용된다. (참고 : http://www.exemwiki.com/?p=2627)

2)Big_block(Block의 크기를 크게 설계)

3)Parallel-query(병렬쿼리)


9. 조인기법

*조인 종류

1)문법즉면

Natural_Join(Equal_Join=Inner_Join)

Cross_Join(Cartesian_Join)

Self-Reference_Join

Outer_Join


2)실행방법 측면

Sort-Merge Join(JOIN에 참여하는 컬럼이 INDEX가 없다. 데이터가 많으면 많을 수록 성능이 보장 안됨)

Nested-Loops Join(JOIN하는데 INDEX를 사용함)

Hash Join(오라클 7.3.3버전부터 Sort-Merge Join를 극복하기 위해 나온 방법, CBO환경에서만 됨)

Cluster Join


9.2 성능에 영향을 주는 요소

1)구동(driving)테이블의 선택(어떤 테이블을 먼저 검색하는가)

2)테이블 조인 순서

3)검색되는 테이블의 데이터량

4)JOIN시 INDEX의 사용여부


9.2.1 구동 테이블의 결정 원리

1)조인에 참여하는 컬럼에 모두 인덱스가 있거나, 모두 없는경우(동등조건)에서는 오른쪽에서 왼쪽순

2)SQL문을 작성하는 개발자에 의해 조인 순서를 결정하는 경우


9.2.2 조인 순서 결정 원리

1)Non-Unique index < Unique

2)싱클컬럼 인덱스 < 결합컬럼 인덱스 


Comments