728x90
반응형
1.인덱스를 왜 안타나요?
1) 인덱스가 존재하지 않는 경우
2) 인덱스가 존재하는데 활용을 못하는 경우
- 선행 컬럼 조건절에 부재
- 선행 컬럼의 조건에 % 가 붙는 경우
- 인덱스 중간 컬럼의 부재
3) 인위적으로 인덱스 사용을 하지 못하도록 한 경우
- 비교 컬럼의 type
- null 비교
4) 옵티마이져의 선택
2, 인덱스를 타는데 왜 느리죠?
1) 데이타의 분포도가 낮은 경우
2) SQL문이 과도하게 호출되는 경우 (Nested loop ==> Hash join)
단 hash join은 = 일 때 가능하다.
3) 또 한 가지 방법으로는 데이터베이스를 사용하지 말고 메모리에 사용정보를 올려서
이를 참조하는 방식이다.
조인되는 테이블이 많아 해시 조인으로도 목표 시간을
획득하기 힘들다면 자주 변하지 않는 정보에 한해 데이터베이스상의 정보를 프로세스
시작시에 메모리로 로드한 뒤 메모리를 참조하라는 뜻이다. 앞의 예와 같이 우편번호
테이블은 거의 변동이 없는 정보이다. 이 정보를 메모리에 올려 사용하더라도 데이터
무결성이 깨질 위험은 적다. 상품 정보, 요율 정보, 각종 코드 정보 등이 이에
해당한다.
하지만 이 방법은 무결성을 깨트릴 위험이 어쨌든 존재하므로 반드시 다른 업무팀과
협의하여 결정해야 하며, 대상 프로세스가 수행시에는 관련 정보를 수정하는 일이
없도록 해야 한다.마지막 방법으로는 LOOP문 안에 SQL문 실행 횟수를 줄이는
좋은 아이디어를 짜내어야 한다. 예를 들어 지역별로 서버가 나눠진 경우라면
우편번호가 같은 고객이 연달아 읽혀질 가능성도 있다. 그렇다면 이전 고객에서 읽혀진
고객 우편번호와 지금 읽혀진 고객 우편번호가 같다면 굳이 우편번호 테이블을
또 읽으러 갈 이유가 없다. 이전 데이터를 메모리에 저장했다가 이 값을 적용하면 된다.
이는 예상 밖의 소득을 올릴 수 있다.
3. 몇천 만 건은 속도가 빨리 나오는데 왜 겨우 100건 조회시에는 느린가요?
1) 부분 범위 처리와 전체 범위 처리의 비교
예: rownum 사용시 : use_nl 과 use_hash 차이
use_nl : 부분범위로 10건만 처리
use_hash: 전체 처리후 10건 추출
4. 건수가 많아 도저히 빠르게 처리가 안된다.
1) parallel processing을 사용한다.
- parallel-to-parallel, serial-to-parallel, parallel-to-serial 중
parallel-to-parallel이 가장 좋은 플랜이다.
5. db문제 인가, sql 문제 인가?
6. oltp 프로그램에서 목표시간내 수행되지 않아요
- "잠시만 기다리세요" message box 사용
7. parallel을 사용하는데 속도가 나지 않는다.
1) parallel이 올바르게 사용되어야 한다. cpu 개수를 과도하게 넘는 경우는
오히려 과부하를 초래한다.
8. 예전에 비해서 속도가 저하된다.
1) 데이타건수 및 분포도 변경
9. 파티션 옵션 사용
10. 결론
[1] 적게 읽거나 적게 실행되도록 노력
- 안 읽어도 될 부분이 읽혀지고 있지는 않은가?
- 결과와 상관없는 데이터가 조인되고 있지는 않은가?
- 한번 읽은 것을 또 읽은 것이 없는가?
- LOOP문 안에서의 SQL문 실행 횟수 제거
- 멀티 블록 액세스(풀 스캔)과 인덱스의 부분 액세스의 대비 분석
- 중첩 루프 방식과 해시 조인 중 어느 것이 나은가?
[2]패러럴(병렬) 처리 기법을 반드시 활용
- 패러럴 옵션의 적절한 활용
- 프로세스 수행 단위를 최소화하여 병렬 처리가 가능토록 조정
- THREAD 기법을 활용한 병렬 프로그래밍 기법 향상
- 작업 스케쥴 수립을 통하여 누수 시간을 방지
참고 : 힌트에 대한 활용
◆ Optimizer 모드에 대한 힌트
- RULE 룰 기반 옵티마이저
- CHOOSE 주로 비용 기반을 유도하고자 할 때 사용
- ALL_ROWS 전체 범위로 처리
- FIRST_ROWS 부분 범위로 처리
◆ ACCESS PATH에 대한 힌트
- FULL : /*+ FULL (테이블명) */
- ROWID : /*+ ROWID (테이블명) */
- CLUSTER : /*+ CLUSTER (테이블명) */ CLUSTER에 사용
- HASH : /*+ HASH (테이블명) */ CLUSTER에 사용
- HASH_AJ : /*+ HASH_AJ */ Not IN시 사용
- HASH_SJ : /*+ HASH_SJ (테이블명) */ EXISTS
- INDEX : /*INDEX (테이블명, 인덱스명1, 인덱스명2…) */
- INDEX_ASC : /*+INDEX_ASC (테이블명, 인덱스명) */
- INDEX_DESC : /*+INDEX_DESC (테이블명, 인덱스명) */
- INDEX_FFS : /*+INDEX_FFS (테이블명, 인덱스명) */
- MERGE_AJ : /*+MERGE_AJ */ NOT IN시 사용
- MERGE_SJ : /*+MERGE_SJ */ EXISTS시 사용
- AND_EQUAL : /*+AND_EQUAL (테이블명, 인덱스명, 인덱스명…) */
- USE_CONCAT : /*+USE_CONCAT */ OR 조건을 UNION ALL로
◆ JOIN 순서에 대한 힌트
- ORDERED : /*+ORDERED */ FROM 절의 순서대로 테이블을 읽음. 반드시 WHERE절을 맞춰야 함
◆ JOIN 연산에 대한 힌트
- USE_NL : /*+USE_NL(테이블명,테이블명,..) */ 중첩 루프 조인 방식
- USE_MERGE : /*+USE_MERGE(테이블명,테이블명,..) */정렬 병합 조인 방식
- USE_HASH : /*+USE_HASH(테이블명,테이블명,..) */ 해시 조인 방식
- DRIVING_SITE : /*+DRIVING_SITE (테이블명, 테이블명,..) */ 원격지 DB에 있는 테이블과 조인시
◆ PARALLEL에 대한 힌트
- PARALLEL : /*+PARALLEL (테이블명, 숫자1, 숫자2) */
- NOPARALLEL : /*+NOPARALLEL (테이블명) */
- APPEND : INSERT /*+APPEND [PARALLEL..] */ 빠른 INSERT시 사용, 중단시 인덱스 깨짐
- NOAPPEND : INSERT /*+NOAPPEND */
- PARALLEL_INDEX : /*+PARALLEL_INDEX (테이블,
- NOPARALLEL_INDEX : /*+NOPARALLEL_INDEX (테이블, 인덱스)*/
◆ 기타
- CACHE : /*+CACHE (테이블명) */
- NOCACHE : /*+NOCACHE (테이블명) */
- MERGE : /*+MERGE (테이블명) */
- NO_MERGE : /*+NO_MERGE (테이블명) */
- PUSH_JOIN_PRED : /*+PUSH_JOIN_PRED (테이블명) */ (PUSH_JOIN_PREDICATE 파라미터 FALSE 설정)
- NO_PUSH_JOIN_PRED : /*+NO_PUSH_JOIN_PRED (테이블명) */ (PUSH_JOIN_PREDICATE 파라미터 TRUE 설정)
- PUSH_SUBQ : /*+PUSH_SUBQ */
출처: microsoft 메거진
728x90
반응형
'DBMS' 카테고리의 다른 글
[기술공유] 실크로드소프트 금융에 혁신을 더하다(CDC솔루션) (0) | 2023.05.01 |
---|---|
DBA가 알아야 할 것들 (0) | 2022.07.20 |