Successfully reported this slideshow.
Your SlideShare is downloading. ×

효율적인Sql작성방법 2주차

Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad

Check these out next

1 of 47 Ad

More Related Content

Slideshows for you (20)

Viewers also liked (20)

Advertisement

Similar to 효율적인Sql작성방법 2주차 (20)

Recently uploaded (20)

Advertisement

효율적인Sql작성방법 2주차

  1. 1. IT역량강화 과정 효율적인 SQL작성방법 2주차 시스템개발3팀 강희동 본서의 모든 이미지 출처는 생략합니다.
  2. 2. ROW ID 조인 시 순서 ROWID 구조 블록간에 유일한 구분 값을 위해 블록 주소 정의 ORACLE에서 INDEX를 생성하기 위해 내부적으로 사용하는 키로 임의 변경,삭제 불가 ROWID는 테이블 형태로 관리 되지 않고 식별키로만 사용 테이블 ROW에 접근하는 가장 빠른 수단 테이블 열 들을(ROWS) 위한 유일한 식별자
  3. 3. ROW ID 조인 시 순서 SELECT ROWID, MBR_ID FROM MBR_MEMBER_MST AAAX5JAARAAB83rAAJ 1000457 AAAX5JAAQAAChKRAAp 1000492 AAAX5JAAQAAChR4AAR 1001132 AAAX5JAARAAB87sAAe 1001135 AAAX5JAARAAB82qAAn 1001144 AAAX5JAARAAB82rAAI 1001505 AAAX5JAAQAAChU7AAa 1001558 AAAX5JAAQAAChU7AAY 1001565 SELECT ROWID, MBR_ID FROM COM_LOGIN_MST AAAXpyAAQAACgWbAAB jangreen AAAXpyAAQAACgWbAAC ngh8751 AAAXpyAAQAACgWbAAD 70533545 AAAXpyAAQAACgWbAAE oji1602 AAAXpyAAQAACgWbAAF chong1210 AAAXpyAAQAACgWbAAG shin0420 AAAXpyAAQAACgWbAAH kjs89 AAAXpyAAQAACgWbAAI choeun90 SELECT ROWID, A.MBR_ID, B.LOGIN_ID FROM MBR_MEMBER_MST A, COM_LOGIN_ID_MST B WHERE A.MBR_ID = B.MBR_ID SELECT A.ROWID, B.ROWID A.MBR_ID, B.LOGIN_ID FROM MBR_MEMBER_MST A, COM_LOGIN_ID_MST B WHERE A.MBR_ID = B.MBR_ID
  4. 4. ROW ID 조인 시 순서 SELECT ROWID, A.* FROM ( SELECT A.ROWID, B.ROWID A.MBR_ID, B.LOGIN_ID FROM MBR_MEMBER_MST A, COM_LOGIN_ID_MST B WHERE A.MBR_ID = B.MBR_ID ) A SELECT ROWID, A.* FROM ( SELECT A.MBR_ID, B.LOGIN_ID FROM MBR_MEMBER_MST A, COM_LOGIN_ID_MST B WHERE A.MBR_ID = B.MBR_ID ) A AAAXpyAAQAACgWbAAB 167132jangreen AAAXpyAAQAACgWbAAC 187917ngh8751 AAAXpyAAQAACgWbAAD 18398870533545 AAAXpyAAQAACgWbAAE 160764oji1602 AAAXpyAAQAACgWbAAF 186335chong1210 AAAXpyAAQAACgWbAAG 161908shin0420 AAAXpyAAQAACgWbAAH 177346kjs89 AAAXpyAAQAACgWbAAI 165904choeun90 A B AAAX5JAANAAHwjkAAV AAAXpyAAQAACgWbAAB 167132 jangreen AAAX5JAANAAHwjkAAW AAAXpyAAQAACgWbAAC 187917 ngh8751 AAAX5JAANAAHwjkAAX AAAXpyAAQAACgWbAAD 183988 70533545 AAAX5JAANAAHwjkAAY AAAXpyAAQAACgWbAAE 160764 oji1602 AAAX5JAANAAHwjnAAb AAAXpyAAQAACgWbAAF 186335 chong1210 AAAX5JAANAAHwjnAAc AAAXpyAAQAACgWbAAG 161908 shin0420 AAAX5JAANAAHwjnAAd AAAXpyAAQAACgWbAAH 177346 kjs89 AAAX5JAANAAHwjnAAe AAAXpyAAQAACgWbAAI 165904 choeun90 ROWID가 작은게 출력
  5. 5. 서브쿼리가 비효율적 인가? 실행 계획을 볼 줄 알면 서브쿼리가 비효율적으로 나올 수 없습니다. 서브쿼리는 집합으로 묶어주는 기능일 뿐이지 성능을 비효율적으로 만들지 않습니다. 멀티캐시 효과 때문에 경우에 따라 오히려 퍼포먼스를 낼 수 있습니다. 서브쿼리는 읽는 범위가 작아야 합니다.
  6. 6. 서브쿼리가 비효율적 인가? SELECT DEPT_NO, COUNT(*) CNT, (SELECT COUNT(*) FROM EMP) TOTALEMP FROM EMP GROUP BY DEPT_NO 변경 후 SELECT DEPTNO, DNAME ,TO_NUMBER(SUBSTR(VAL, 1,10)) AVG_SAL ,TO_NUMBER(SUBSTR(VAL, 11,10)) MIN_SAL ,TO_NUMBER(SUBSTR(VAL, 21)) MAX_SAL FROM ( SELECT D.DEPTNO, D.DNAME, (SELECT LPAD(AVG(SAL),10)||LPAD(MIN(SAL),10)||MAX(SAL) FROM EMP WHERE DEPTNO = D.DEPTNO)VAL FROM DEPT D WHERE D.LOC = 'LA' ) 안 좋은 예) 변경 전 SELECT D.DEPTNO, D.DNAME. AVG_SAL, MIN_SAL, MAX_SAL FROM DEPT D, (SELECT DEPTNO, AVG(SAL) AVG_SAL, MIN(SAL) MIN_SAL, MAX(SAL) MAX_SAL FROM EMP GROUP BY DEPTNO)E WHERE E.DEPTNO(+) = D.DEPTNO AND D.LOC = 'LA' -불필요한 사원 집합 발생 -OUTER JOIN으로 인한 E 드라이빙 -사원 테이블에 넓은 영역 집합 함수 -효율적인 사원 집합 추출 -OUTER JOIN을제거하여 D부터 드라이빙 -사원 테이블에 좁은 영역에 집합 함수 -서브쿼리를 CONCATENATE 사용
  7. 7. 1주차 Review
  8. 8. Programming vs SQL Programming SQL public int aa(int a, int b)throws Exception{ int c = 0; if(a == b){ return a; }else{ return b; } } public String getMaxNumber(int iNum1, int iNum2)throws Exception{ return iNum1 > iNum2 ? iNum1 : iNum2; } SELECT * FROM ( SELECT ROWNUM RN , A.* FROM EMP A WHERE ENAME LIKE ‘강%’ AND JOB <> ‘SALES’ AND (STATUS = ‘1’ OR STATUS = ‘2’) ) WHERE RN BETWEEN 1 AND 10 SELECT * FROM ( SELECT ROWNUM RN , A.* FROM EMP A WHERE ENAME LIKE ‘강%’ AND NOT EXISTS(SELECT 1 FROM EMP B WHERE B.EMPNO = A.EMPNO AND JOB = ‘SALES’ AND ROWNUM = 1) AND STATUS IN (‘1’, ‘2’) AND ROWNUM <= 10 ) WHERE RN >= 1
  9. 9. 절차형 사고 버리기 SELECT * FROM MNS A, SKP B, SKT C WHERE A.조건 = B.조건 AND B.조건 = C.조건 AND C.조건 = ‘1234’
  10. 10. Driving의 중요성 TABLE1 TABLE2 TABLE3 (10000 row) (1000 row) (2 row) . . . 1 A 2 C 3 D 4 K 5 M 6 F 7 E 8 M . . . . . . . . A 가 P 나 C 라 H 사 . . . E 마 라 10 마 20 최소 10,000회 이상 ACCESS TABLE3 TABLE2 TABLE1 (10000 row) (2 row) 라 10 마 20 (1000 row) A 가 P 나 C 라 S 마 . . . E 마 1 A 2 C 3 D 4 K 5 M 6 F 7 E 8 M . . . . . . . . 최대 6회 이하 ACCESS
  11. 11. Driving의 중요성 TABLE1 TABLE2 TABLE3 (10000 row) (1000 row) (2 row) . . . 1 A 2 C 3 D 4 K 5 M 6 F 7 E 8 M . . . . . . . . A 가 P 나 C 라 H 사 . . . E 마 라 10 마 20 -TABLE1을 무조건 읽어야 한다면 그 다음에 올 DRIVNING 순서를 예측 -똑같은 조건 이라면 M이 아닌 1 부터 DRIVING TABLE1 TABLE3 TABLE2 (1000 row) (10000 row) (2 row) . . . 1 A 2 C 3 D 4 K 5 M 6 F 7 E 8 M . . . . . . . . C 10 E 20 A 가 P 나 C 라 S 마 . . . E 마
  12. 12. Optimizer select col1, col2*10, . . from account x, custommer y, transection z where x.acct = z.acct and y.cust = z.cust and jdate = ‘130319’; SQL OPTIMIZER DATA Dictionary SQL 해석 COL$ IND$ OBJ$ TAB$ VIEW$ 참 조 실행 customer transaction account DATA 추 출 실행 계획 작성 참 조 ㄴㅍㄴㅇㄹㅇㄹㄴ 률ㄷㄱ34346 ㅓㅏㄴ아ㅓㅗㄴㅇ ㅓㅜㄴ야ㄷㅈㄷㅂ저 ㅊ리아ㅡㄹ ㅏㅡ치ㅏ ㅜ ㅓ투 93 ㅑㅇ너ㅓㅇㄹ너ㅐㅇ러ㅐㄿㄹㅇㄹ ㅓㅜㄴ ㅑ ㅑㅕㅜㅑ ㅜ랸웅ㄴ ㅑ어ㅐ우ㅐㅇ눈애ㅓ래ㅓㅐ앵래 8ㅈ9ㅗ9 ㅗㅑ야 ㅏㄴ어ㅐ B BB JHBJB M M J ㅐㅜ ㅜㄹ울 애ㅣㅓ애럴애ㅓㄹ애 ㅐ ㄹ앙ㄹㄹ이ㅏㅡㅈ냐ㅈㄷㅂ989ㅈ돌ㅍㄴㅇㄴ ㄴ어ㅐㅑㅓ내ㅑ ㄴㅍㄴㅇㄹㅇㄹㄴ 률ㄷㄱ34346 ㅓㅏㄴ아ㅓㅗㄴㅇ ㅓㅜㄴ야ㄷㅈㄷㅂ저 ㅊ리아ㅡㄹ ㅏㅡ치ㅏ ㅜ ㅓ투 93 ㅑㅇ너ㅓㅇㄹ너ㅐㅇ러ㅐㄿㄹㅇㄹ ㅓㅜㄴ ㅑㅕㅇ ㅑㅕㅜㅑ ㅜ랸웅ㄴ ㅑ어ㅐ우ㅐㅇ눈애ㅓ래ㅓㅐ앵래 8ㅈ9ㅗ9 ㅗ ㅑ야 ㅏㄴ어ㅐㅑ퍼ㅐㅜ ㅜㄹ울 애ㅣㅓ애럴애ㅓㄹ애 ㅐ ㄹ앙ㄹㄹ이ㅏㅡㅈ냐ㅈㄷㅂ 결 과  사용자는 요구만 하고 OPTIMIZER가 실행계획 수립  수립된 실행계획에 따라 엄청난 수행 속도 차이 발생  실행계획 제어가 어렵다.  OPTIMIZER가 좋은 실행계획을 수립 할 수 있도록 종합적이고 전략적인 FACTOR를 부여  비절차형으로 기술해야 함  집합적으로 접근해야 함
  13. 13. Optimizer SQL Parsing Optimization Row-Source Execution Parser Optimizer Row-Source Generator SQL EngineParsed SQL Execution Plan Row-Source 1.Query Transformer 2.Estimator 3.Plan Generator
  14. 14. Optimizer SELECT * FROM EMP WHERE ENAME LIKE 'AB%' AND EMPNO = '7890' SELECT * FROM EMP WHERE ENAME LIKE 'AB%' AND JOB LIKE 'SA%' Rule based Cost based SELECT * FROM EMP WHERE ENAME LIKE 'AB%' AND EMPNO = '7890' SELECT * FROM EMP WHERE ENAME LIKE 'AB%' AND JOB LIKE 'SA%' SELECT * FROM EMP WHERE JOB = 'SALESMAN' AND EMPNO = '7890' 나중에 생성된 Index 사용 SELECT * FROM EMP WHERE JOB = 'SALESMAN' AND EMPNO = '7890' 분포도에 따라 ENAME index 도 사용 INDEX merge (and_equel), 특정 index 분포도에 따라 index 사용, 혹은 full scan 항상 EMPNO Index만 사용 INDEX merge (and_equel)
  15. 15. 전체범위 VS 부분범위 전 체 범 위 처 리 2 차 가 공 운반단위 • • • • 1 차 스 캔 Full Range Scan 후 가공하여 Array Size 만큼 추출 부 분 범 위 처 리 2 차 가 공 운반단위 1 차 스 캔 조건을 만족하는 Row 수가 Array Size 에 도달되면 멈춤
  16. 16. 전체범위 VS 부분범위 2 차 가 공 운반 단위 TAB1 TAB2 . . . . . . . . . . . .
  17. 17. 전체범위 VS 부분범위 INDEX SCAN FULL SCAN
  18. 18. SORT를 대신하는 INDEX 실습 회원 정보를 이름 + 생년월일 순으로 descending정렬해서 모든 데이터를 가져 오시오. 추가되어야 할 인덱스를 정의 하시고 SQL문을 작성하세요. 단, ORDER BY를 사용하지 말고 INDEX를 활용해서 하세요 인덱스 명 : 회원_PK (회원ID) SELECT * FROM 회원
  19. 19. 부분범위 처리 예제 SORT를 대신하는 INDEX SELECT * FROM PRODUCT WHERE YMD = ‘130321' AND ITEM LIKE 'AB%' ORDER BY YMD, ITEM 운반단위 전 체 스 캔 INDEX (YMD) TABLE S O R T . . . . . . . . SELECT * FROM PRODUCT WHERE YMD = ‘130321' AND ITEM LIKE 'AB%' 운반단위 부 분 스 캔 INDEX (YMD+ITEM) TABLE
  20. 20. 부분범위 처리 예제 INDEX만 읽고 처리 SELECT DEPT, SUM(QTY) FROM PRODUCT WHERE DEPT LIKE '12%' GROUP BY DEPT; 운반단위 INDEX (DEPT) TABLE • • G R O U P B Y• • SELECT DEPT, SUM(QTY). FROM PRODUCT WHERE DEPT LIKE '12%' GROUP BY DEPT; 운반단위 INDEX (DEPT+QTY) G R O U P B Y • • • •
  21. 21. 부분범위 처리 예제 INDEX만 읽고 처리(예제) INDEX 정보 TF_ORD_I3 (ITEM, STATUS) SQL> SELECT STATUS, COUNT(*) FROM TF_ORDER WHERE ITEM LIKE 'HJ%' GROUP BY STATUS 20 SORT GROUP BY 36631 INDEX RANGE SCAN TF_ORD_I3 2.5 sec20 SORT GROUP BY 36630 TABLE ACCESS BY ROWID TF_ORDER 36631 INDEX RANGE SCAN TF_ORD_I3 SQL> SELECT TYPE, COUNT(*) FROM TF_ORDER WHERE ITEM LIKE 'HJ%' GROUP BY TYPE 10.3 sec
  22. 22. 부분범위 처리 예제 MAX 처리 SELECT MAX(SEQ) + 1 FROM PRODUCT WHERE DEPT = '12300'; 운반단위 INDEX (DEPT) TABLE • • S O R T • • MAX(SEQ)+1 SELECT /*+ INDEX_DESC( A INDEX1) */ SEQ + 1 FROM PRODUCT A WHERE DEPT = '12300' AND ROWNUM = 1; 운반단위 INDEX (DEPT+SEQ) SEQ + 1
  23. 23. 부분범위 처리 예제 ROWNUM의 활용 SELECT COUNT(*) INTO :CNT FROM ITEM_TAB WHERE DEPT = '101' AND SEQ > 100 . . . . . . . IF CNT > 0 . . . . . . . . . . INDEX (DEPT) TABLE . . . . . ..... 운반 단위 COUNT SELECT 1 INTO :CNT FROM ITEM_TAB WHERE DEPT = '101' AND SEQ > 100 AND ROWNUM = 1 . . . . . . . . IF CNT > 0 . . . . . . . . INDEX (DEPT) TABLE 운반 단위 X O
  24. 24. 핵심 포인트! 집합적 사고 Optimizer 부분범위 처리 3가지를 꼭 기억하세요!
  25. 25. 2주차 강의
  26. 26. 다양한 인덱스 스캔 방식
  27. 27. INDEX를 사용 못하게 되는 경우와 사례 INDEX COLUMN의 변형 SELECT * FROM DEPT WHERE SUBSTR(DNAME,1,3) = 'ABC' NOT Operator NULL, NOT NULL Optimizer 의 취사선택 SELECT * FROM EMP WHERE JOB <> 'SALES' SELECT * FROM EMP WHERE ENAME IS NOT NULL SELECT * FROM EMP WHERE JOB LIKE 'AB%' AND EMPNO = '7890' Function Based Index 사용시는 예외
  28. 28. 다양한 인덱스 스캔 방식 어떤 골프채로 쳐야 할까요? = 어떤 인덱스 스캔 방식을 써야 효율적일까요?
  29. 29. 다양한 인덱스 스캔 방식
  30. 30. INDEX UNIQUE SCAN Unique Scan =인덱스의 모든 컬럼 매칭 한 건 Equal 데이터 한 건 추출 범위검색 조건(between, 부등호, like) 인 경우 Range Scan 으로 검색(한 건 이상 이기 때문) (Unique Index 생성 시)
  31. 31. INDEX Range Scan / Descending INDEX UNIQE SCAN INDEX RANGE SCAN CREATE UNIQUE INDEX 인덱스명 CREATE INDEX 인덱스명 Unique Scan Range Scan
  32. 32. INDEX Range Scan / Descending INDEX UNIQE SCAN INDEX RANGE SCAN > 데이터 추출 시 인덱스 컬럼 순으로 정렬 ORDER BY , MIN, MAX 값을 대체 가능 선두 컬럼이 조건절에 사용 되지 않으면 INDEX FULL SCAN 발생 인덱스를 스캔하는 범위를 얼마만큼 줄이고 테이블 엑세스를 적게 하는게 속도향상 포인트 Range Scan Descending
  33. 33. INDEX SKIP SCAN 인덱스 : 기준일자 + 업종코드 SELECT /*+INDEX(A 일별업종별거래_IDX)*/ 기준일자, 업종코드, 체결건수, 체결수량, 거래대금 FROM 일별업종별거래 A WHERE 기준일자 BETWEEN ‘20130701’ AND ‘20130709’ AND 업종코드 = ‘01’ INDEX RANGE SCAN SELECT /*+INDEX(A 일별업종별거래_IDX)*/ 기준일자, 업종코드, 체결건수, 체결수량, 거래대금 FROM 일별업종별거래 A WHERE 업종코드 = ’01’ INDEX SKIP SCAN Oracle 9i부터 사용가능 중복된 값이 많을 수록 유리
  34. 34. INDEX FULL SCAN Full Scan INDEX UNIQE SCAN INDEX RANGE SCAN > >INDEX SKIP SCAN >TABLE FULL SCAN >INDEX FULL SCAN <?>TABLE FULL SCAN INDEX FULL SCAN (효율?) SELECT * FROM EMP WHERE SAL > 5000 ORDER BY EMP_NAME 데이터 건이 많으면 Random Access발생으로 TABLE FULL SCAN을 이용 해야 효율적 데이터 량이 많아지면 I/O낭비가 심해짐 데이터 건이 극히 일부일 때만 TABLE FULL SCAN 보다 유리함. INDEX와 마찬가지로 ORDER BY 사용 가능 대부분 인덱스가 차지하는 면적이 테이블보다 작음
  35. 35. INDEX FAST FULL SCAN
  36. 36. INDEX FAST FULL SCAN Index Full Scan 방식 : 1번 브랜치 > 1 > 2 > 3 > 4 > 5 > 6 > 7 > 8 > 9 > 10 Index Fast Full Scan 방식 : 1 >2>10>3>9>8>7>4>5>6 순서대로 전체를 읽음
  37. 37. INDEX FAST FULL SCAN INDEX FULL SCAN INDEX FAST FULL SCAN 1.인덱스 구조를 따라 스캔 1.세그먼트 전체를 스캔 2.결과집합 순서 보장 2.결과집합 순서 보장 안 됨 3.Single Block I/O 3.Multiblock I/O(세그먼트 전체스캔) 4.병렬스캔 불가(파티션 돼 있지 않다면) 4.병렬스캔 가능 5.인덱스에 포함되지 않은 컬럼 조회시에도 사용가능 5.인덱스에 포함된 컬럼으로만 조회할 때 사용 가능 SELECT * FROM 공급업체 WHERE 업체명 LIKE ‘%네트웍스%’ SELECT /*+ORDERED USE_NL(B) NO_MERGE(B) ROWID(B)*/ B.* FROM ( SELECT /*+INDEX_FFS(공급업체 공급업체_IDX)*/ ROWID AS RID FROM 공급업체 WHERE INSTR(업체명,’네트웍스’) > 0 )A, 공급업체 B WHERE B.ROWID = A.RID 10g 부터는 index range or full scan 일 때도 Multiblock I/O스캔발생 (인덱스만 읽을 때)
  38. 38. INDEX MERGE INDEX MERGE와 결합 INDEX 비교 INDEX (COL1) COL1 rowid COL2 rowid . . . . . . 100 29 105 10 123 7 123 9 123 32 123 35 123 46 123 52 123 56 123 65 123 67 123 68 123 75 . . . . . . ABC 10 ABC 15 ABC 26 ABC 28 ABC 32 ABC 67 BCA 12 BCA 27 BCA 56 BCA 85 CBA 35 CBA 46 CBA 64 CBA 99 . . . . . . . INDEX (COL2) ABC 55 10 ABC 67 15 ABC 89 26 ABC 100 29 ABC 123 32 ABC 123 67 ABC 180 76 BCA 100 12 BCA 100 27 BCA 123 56 BCA 123 85 CBA 85 35 CBA 123 46 CBA 214 64 . . . . . . . . . COL1 COL2 rowid INDEX (COL1 + COL2) 결합 INDEXINDEX MERGE
  39. 39. AND-EQUAL SELECT CUSTNO, CHULDATE FROM CHULGOT WHERE CUSTNO = 'DN02' AND STATUS = '90' SELECT CUSTNO, CHULDATE FROM CHULGOT WHERE CUSTNO LIKE 'DN%' AND RTRIM(STATUS) LIKE '9%' TABLE ACCESS BY ROWID CHULGOT AND-EQUAL INDEX RANGE SCAN CH_STATUS INDEX RANGE SCAN CH_CUSTNO SELECT CUSTNO, CHULDATE FROM CHULGOT WHERE CUSTNO LIKE 'DN%' AND STATUS LIKE '9%' Oracle 10g부터 폐기된 기능입니다! 10g 이하버젼을 쓰시는 분만 참고하세요.
  40. 40. RANDOM ACCESS 운반 단위 INDEX (FLD) ..... 2 차 가 공 TAB TAB 운반 단위 o x o o o x o x ..... x x 2 차 가 공 o o Index Range Scan Full Table Scan RANDOM ACCESS가 많이 발생되면 I/O효율이 떨어집니다.
  41. 41. BITMAP SELECT count(*) FROM parts WHERE size = 'MED' AND color = 'RED' Index on COLOR color = 'BLUE' 0 0 0 1 0 0 1 0 1 0 1 0 0 0 1 0 color = 'RED' 0 1 1 0 1 0 0 1 0 0 0 0 1 0 0 1 color = 'GREEN' 1 0 0 0 0 1 0 0 0 1 0 1 0 1 0 0 Index on SIZE size = 'SMALL' 0 0 1 0 0 1 0 1 0 1 0 0 0 1 0 1 size = 'MED' 1 1 0 0 1 0 1 0 0 0 0 1 0 1 0 0 size = 'LARGE' 0 0 0 1 0 0 0 0 1 0 1 0 1 0 1 0 0 1 0 0 1 0 PARTS table 001 GREEN MED 98.1 002 RED MED 1241 003 RED SMALL 100.1 004 BLUE LARGE 54.9 005 RED MED 124.1 006 GREEN SMALL 60.1 ... .... ..... ... partno color size weight 0 1 0 0 1 0
  42. 42. BITMAP 상품ID 상품명 색상 1 AAA GREEN 2 BBB GREEN 3 CCC RED 4 DDD BLUE 5 EEE RED 6 FFF GREEN 7 GGG BLUE 8 HHH 9 JJJ RED BLUE GREEN RED NULL 0 1 0 0 0 1 0 0 0 0 1 0 1 0 0 0 0 0 1 0 0 1 0 0 1 0 0 0 0 0 0 1 0 0 1 0 테이블 저장 데이터
  43. 43. BITMAP B*Tree INDEX
  44. 44. BITMAP BITMAP INDEX
  45. 45. BITMAP BITMAP INDEX 레코드 찾아가는 방법 Block안에 저장할 수 있는 최대 Record 개수 730개 테이블에 20개 BLOCK이 할당이 되어있다고 가정 730 X 20 = 14600 9500번째가 1라면 BLOCK 위치 : 9500 / 730 = 13 Record 위치 : MOD(9500 / 730) = 10
  46. 46. 마무리 INDEX RANGE SCAN INDEX SKIP SCAN INDEX FAST FULL SCAN INDEXUNIQUESCAN FULL SCAN
  47. 47. 마무리

Editor's Notes

  • Statement, prestatement
    바인딩 단점을 보완한 바인딩변수 peeking : 하드파싱 시 컬럼분포도를 이용해 통계정보를 만들어낸다
    -SQL 파서가 파싱
    반복사용하기 위해 라이브러리 캐쉬에 저장( 커서 공유)
    -최적화하기 쉬운형태로 변환
    후보군이 될만한 실행계획들 생성
    오브젝트 통계정보, 시스템 성능 통계정보를 이용하여 필요한 I/O, CPU, 메모리 사용량 등을 예측
    -SQL 실행계획 생성

  • Table Full Scan 보다 I/O를 줄일 수 있거나 정렬된 결과를 쉽게 얻을수 있다면 Index Full Scan방식 사용

×