ORACLE/TUNING2015. 4. 25. 23:21
반응형

PURPOSE
 
부정형의 비교를 긍정형 비교로 바꾸어서 인덱스 사용을 유도하는 방법에 대해서 알아본다.


KEY IDEA
 
부정형의 비교에는 논리적으로 인덱스를 사용할 수 없다. 하지만 약간의 IDEA를 첨부한다면
부정형의 비교를 긍정형의 비교로 바꾸어서 인덱스의 사용을 유도할 수 있다.
(KEY WORD : INDEX 활용, 인덱스, 부정형 비교, NOT IN, NOT EXISTS, <> )


DESCRIPTION
  
다음의 SQL을 보자.
     SELECT ‘Not found’  FROM EMP WHERE EMPNO <> ‘1234’

  • 대개의 Application에서는 사용자가 처리한 데이터의 타당성을 검증하기 위해 이 값의
    존재 유무를 확인하는 경우가 빈번하게 발생한다.  
    이럴 경우 위의 예처럼 부정형의 문장을 사용하는 경우가 자주 있다.

  • 하지만 아래와 같이 ‘NOT EXISTS’를 이용해서 서브쿼리(SUB-QUERY)내의 SQL을 긍정형으로 바꾸면 인덱스를 사용할 수 있다.

     SELECT ‘NOT FOUND’ FROM DUAL
        WHERE NOT EXISTS ( SELECT ‘X’ FROM EMP WHERE EMPNO = ‘1234’ )

  • 그러나 ‘EXISTS’를 사용하는 것이 항상 유리한 것은 아니다. 다음의 3개의 SQL을 보자.

    [SQL1]
      SELECT * FROM TAB1
         WHERE YYYYMM = ‘199910’
             AND NOT EXISTS ( SELECT * FROM TAB2
                                       WHERE COL2 = COL1
                                           AND YYYYMM = ‘199910’ )
    [SQL2]
      SELECT * FROM TAB1
          WHERE YYYYMM =’199910’
              AND COL1 NOT IN (SELECT COL2 FROM TAB2
                                           WHERE YYYYMM = ‘199910’ )
    [SQL3]
       SELECT * FROM TAB1
           WHERE (YYYYMM, COL1) IN ( SELECT ‘199910’, COL1 FROM TAB1
                                                       WHERE YYYYMM = ‘199910’
                                                   MINUS
                                                   SELECT ‘199910’, COL2 FROM TAB2
                                                        WHERE YYYYMM = ‘199910’ )

  • TAB1 테이블의 ‘YYYYMM’, ‘COL1’이 각각 인덱스로 생성되어 있고
    TAB2의 ‘YYYYMM’, ‘COL2’가 각각 인덱스로 생성되어 있다.
     
  • [SQL1] 은 ‘TAB1’의 ‘YYYYMM’ 인덱스만을 사용하여 테이블의 로우를 엑세스하고
    각 로우마다 TAB2 테이블을 엑세스하는 서브쿼리가 수행되어 TAB2 에 존재하지 않는
    로우만 추출하게 된다. 이 SQL은 ‘199910’조건에 해당하는 모든 로우에 대해 서브
    쿼리가 랜덤엑세스를 수행한다. 왜냐하면 서브쿼리내에 메인쿼리의 컬럼인 'COL1'이
    존재하기 때문
    이다.
     
  • [SQL2] 는 서브쿼리 내에 메인쿼리 컬럼을 없애기 위해 작성하였지만 동일한 결과를
    초래한다. 그 이유는 'NOT IN'을 사용한 서브쿼리는 항상 나중에 수행되거나
    필터링(Filtering) 조인방식으로 수행되기 때문
    이다.
     
  • [SQL3]은 각 테이블에 ‘YYYYMM + COL1’, ‘YYYYMM + COL2’의 결합인덱스가 존재한
    다면 먼저 서브쿼리에서 두 개의 테이블을 ‘MINUS’하여 결과를 추출하고 그 결과를
    이용해 메인쿼리를 엑세스하게 할 수 있다. 이 경우에는 서브쿼리가 먼저 수행된다.
    인덱스만으로도 처리가 가능하기 때문에 테이블을 엑세스하지 않고 양쪽 테이블의
    인덱스들만 범위스캔(Range Scan)하여 ‘SORT-MERGE’방식으로 서브쿼리가 처리 된다.
     
  • 위의 경우에서는 결과적으로 [SQL3]가 가장 유리한 처리방법이라 하겠다.

참고 : http://kdonghwa.tistory.com/58?srchid=BR1http%3A%2F%2Fkdonghwa.tistory.com%2F58

반응형
Posted by [PineTree]
ORACLE/TUNING2015. 4. 25. 23:17
반응형

* 인덱스를 타지 않는 SQL
1. 인덱스 컬럼 절의 변형
2. 내부적인 데이터 변환
3. NULL 조건의 사용
4. 부정형 조건의 사용
5. LIKE 연산자 사용
6. 최적기가 판단


1 - 인덱스 컬럼 절의 변형
SQL> select ename from emp where sal * 2.1 > 950 --인덱스 사용불가
SQL> select ename from emp where sal > 950 /2.1  --인덱스 사용가능
SQL> select ename from emp where to_char(hiredate,'DDMMYY') = '250884' --인덱스 사용불가
SQL> select ename from emp where hiredate = to_date('250884','DDMMYY') --인덱스 사용가능

-> 인덱스 컬럼에 변형을 가하면은 사용할수 없습니다. 단 변형 가능하더라도 쓰고 싶다면은
    말리지는 않겠지만 create index .... on emp to_char(hiredate,'DDMMYY') 이렇게 하시면 됩니다.


2 - 내부적인 데이터 변환
SQL> select * from emp where hiredate ='14-JAN-85' --인덱스 사용불가
SQL> select * from emp hiredate = to_date('71-10-22','YY/DD/DD') --인덱스 사용가능
SQL> select * from emp where empno = '7936' --인덱스 사용불가
SQL> select * from emp where empno = to_number('7936') --인덱스 사용가능

-> 내부적인 데이터변환에서 가장 많이 실수하는 부분은 문자값 데이터타입을 갖는 컬럼에
    '값' -> 값 이렇게 하시는분이 많습니다. 딱맞는 데이터타입을 주세요 ^_^


3 - NULL 조건의 사용
SQL> select ename from emp where comm is null --인덱스 사용불가
SQL> select ename from emp where comm is not null --인덱스 사용불가
SQL> select ename from emp where ename > '' --인덱스 사용가능
SQL> select ename from emp where comm >= 0 --인덱스 사용가능

-> NULL조건으로 검색한다는 가정하에는 거의 인덱스 풀 스캔이 일어나겠죠. 적절히 사용합씨다.


4 - 부정형 조건의 사용
SQL> select ename from emp where deptno != 30 --인덱스 사용불가
SQL> select ename from emp where deptno < 30 and deptno > 30 --인덱스 사용가능

-> 논리적으로 부정형을 이용하여 인덱스를 사용하겠다는것은 말이 안되죠...
    이 쿼리문도 적절히 사용합씨다.


5 - Like 연산자 사용
SQL> select * from emp where ename like 'S%' --인덱스 사용가능
SQL> select * from emp where ename like '%S%' --인덱스 사용불가

-> %S% 부분을 꼭 쓰고싶다면은 이렇게 하세요 앞에부분을 다 넣는거죠. AS%, BS%...
    요즘 홈피를 보면 본문 찾기는 거의 없어져가고 있죠. 엔코아 경우 주제어를 검색을..


6 - 최적기가 판단

-> RBO경우 무조건 타죠 있으면은 이눔은 워낙 법을 좋아해서리..CBO는 통계값을 기준으로
    하기 때문에 DBA가 잘 해야겠죠. 그럼 우리가 판단하게 할라면은 HINT를 써서 이눔들을
    인도해야죠... 오늘도 전도를 ^____^


마지막으로 인덱스를 이용한 sort 회피 방법에 대해서 알아보겠습니다.
SQL> select empno, ename, job, comm from emp order by empno --sort 정렬
SQL> select empno, ename, job, comm from emp where empno >= 0 --sort 정렬제거

-> 인덱스는 값이 정렬되어 들어가있는 구조이기 때문에 처음부터 작은값 맨 끝값은
    최대값이 있겠죠. 잘 사용하면 최고의 튜닝이 되겠죠.


반응형

'ORACLE > TUNING' 카테고리의 다른 글

[Oracle] 부정형(NOT IN, <>, NOT EXISTS ...)의 비교  (0) 2015.04.25
DBMS_XPLAN.DISPLAY_CURSOR 결과 보는 법  (0) 2013.06.23
Sort Area 크기 조정  (0) 2012.09.07
SORT와 PGA_AGGREGATE_TARGET  (0) 2012.09.06
PGA(Program Global Area) 관리  (0) 2012.09.06
Posted by [PineTree]
ORACLE/SCRIPT2010. 4. 28. 14:13
반응형

현재 유저의 인덱스와 관련된 전반적인  정보 조회

SELECT A.TABLE_NAME,
       A.INDEX_NAME,
       B.COLUMN_NAME,
       B.COLUMN_POSITION,
       A.UNIQUENESS,
       B.DESCEND,
       A.INDEX_TYPE,
       A.TABLESPACE_NAME
FROM   USER_INDEXES A,
       USER_IND_COLUMNS B
WHERE  A.INDEX_NAME=B.INDEX_NAME
ORDER BY 1,2,4;


해당 테이블 조회시에는  WHERE 조건에 TABLE_NAME 만 추가해주면 된다.

SELECT A.TABLE_NAME,
       A.INDEX_NAME,
       B.COLUMN_NAME,
       B.COLUMN_POSITION,
       A.UNIQUENESS,
       B.DESCEND,
       A.INDEX_TYPE,
       A.TABLESPACE_NAME
FROM   USER_INDEXES A,
       USER_IND_COLUMNS B
WHERE  A.INDEX_NAME=B.INDEX_NAME AND A.TABLE_NAME='테이블명'
ORDER BY 1,2,4;

TABLE 정보 조회

SELECT TABLE_NAME,COLUMN_NAME,DATA_TYPE,DATA_LENGTH,COLUMN_ID,NULLABLE
FROM USER_TAB_COLUMNS
ORDER BY 1,5
반응형

'ORACLE > SCRIPT' 카테고리의 다른 글

ORACLE 중복 데이터 확인  (0) 2010.05.28
OPTEIMIZING ORACLE OPTIMIZER 스크립트 모음  (0) 2010.04.28
과도한 I/O 유발 쿼리 찾기  (0) 2010.04.15
오라클 시스템 uptime 확인하는 쿼리  (0) 2010.02.25
제약조건 확인  (0) 2010.01.03
Posted by [PineTree]
ORACLE/ADMIN2009. 7. 3. 19:43
반응형

1. 분석 자료의 수집


인덱스 분석 자료를 수집 합니다.

  - 모든 인덱스 블록을 검사하여 블록 훼손을 조사합니다.     

  - 인덱스에 대한 정보를 가지고 있는 INDEX_STATS 데이터 사전에 기록 됩니다.
 
 




SQLPLUS storm/storm


-- 인덱스 분석
SQL>ANALYZE INDEX board_pk VALIDATE STRUCTURE;
 
인덱스가 분석 되었습니다.

 


2. 인덱스 분석 수집 정보 확인
 

 ANALYZE INDEX명령을 수행 한 후 INDEX_STATS를 조회 합니다.
  
SQL>SELECT blocks,  btree_space,  used_space,  pct_used "사용율(%)",
                    lf_rows,  del_lf_rows "삭제행"
        FROM  INDEX_STATS;
  
  
      BLOCKS BTREE_SPACE USED_SPACE  사용율(%)    LF_ROWS     삭제행
   ---------- -----------    ----------       ----------    ----------    ----------
         5          23984             12489                53                  892            51
1 row selected.
 
 
  - 인덱스가 삭제된 행이 많으면 인덱스를 재구축 해야 합니다.

  - 예를 들어 LF_ROW에 대한 DEL_LF_ROWS의 비가 30%를 초과하면 인덱스를 재구축 해야 합니다.
  
 
-- 인덱스의 재구축..
SQL>ALTER INDEX board_pk
        REBUILD  ;

 인덱스가 변경되었습니다.
 
 
-- 분석 자료의 수집
SQL>ANALYZE INDEX board_pk VALIDATE STRUCTURE;
 
인덱스가 분석되었습니다.
 
 
-- 다시 index_stats를 조회 하면 삭제행이 0으로 나오는 것을 확인 할 수 있습니다.
SQL>SELECT blocks, btree_space, used_space, pct_used "사용율(%)",
                   lf_rows, del_lf_rows "삭제행"
        FROM INDEX_STATS;
 
    BLOCKS BTREE_SPACE USED_SPACE  사용율(%)    LF_ROWS     삭제행
   ---------- -----------    ----------    ----------    ----------    ----------
              5          24032         11775              49                841              0
 

  ================================================
    * 데이터베이스 정보공유 커뮤니티 oracleclub.com
    * 강좌 작성자 : 김정식 (oramaster _at_ naver.com)
  ================================================
※ oracleclub 강좌를 다른 웹 페이지에 게재할 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^^
※ oracleclub 강좌는 개인의 학습용으로만 사용 할 수 있습니다. 학원 홍보용이나 수익을 얻기 위한 용도로
    사용을 하시면 안됩니다. ^^
반응형
Posted by [PineTree]
ORACLE/ADMIN2009. 3. 20. 11:11
반응형
인덱스 정보 보기
select a.index_name,b.table_name,column_name,COLUMN_POSITION,UNIQUENESS,tablespace_name,table_owner
from ind a, USER_IND_COLUMNS b
where a.index_name=b.index_name
order by a.index_name,COLUMN_POSITION
반응형

'ORACLE > ADMIN' 카테고리의 다른 글

ORACLE Data Pump  (0) 2009.04.02
as sysdba로 접속시 암호 물어보게 하는 방법  (0) 2009.03.27
em 삭제하고 재 설치  (0) 2009.03.19
TABLE별 용량을 파악해보자!  (0) 2009.03.13
유용한 DICTIONARY 뷰 ..  (0) 2009.03.06
Posted by [PineTree]
ORACLE/SCRIPT2008. 12. 13. 16:13
반응형

/***********************************************
* 테이블명으로 테이블 인덱스정보조회
***********************************************/
col index_name format a15
col table_name format a15
col column_name format a15
SELECT   ICOL.INDEX_NAME  AS INDEX_NAME
          , ICOL.TABLE_NAME  AS TABLE_NAME
          , ICOL.COLUMN_NAME  AS COLUMN_NAME
FROM     DBA_OBJECTS  OBJE
          , DBA_IND_COLUMNS  ICOL
WHERE    OBJE.OBJECT_TYPE   = 'TABLE'
AND       OBJE.OBJECT_NAME   = '테이블명'
AND        ICOL.TABLE_NAME    = OBJE.OBJECT_NAME
ORDER BY ICOL.INDEX_NAME
             , ICOL.COLUMN_POSITION
반응형

'ORACLE > SCRIPT' 카테고리의 다른 글

오라클 성능고도화원리 스크립트파일  (0) 2009.09.04
인덱스 및 테이블 사이즈 보기  (0) 2009.09.02
oracle script  (0) 2009.08.28
유용한 오라클 스크립트..  (0) 2009.08.28
테이블 스페이스 용량 확인 쿼리  (0) 2009.06.10
Posted by [PineTree]