ecdevday8 웹개발자의 약한고리 SQL 뛰어넘기

2,204 views

Published on

웹개발자의 약한고리 SQL 뛰어넘기
박광일

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,204
On SlideShare
0
From Embeds
0
Number of Embeds
47
Actions
Shares
0
Downloads
0
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

ecdevday8 웹개발자의 약한고리 SQL 뛰어넘기

  1. 1. 레인 시간 구분 강사 제목 19:00 ~ 21:00 UI 김정범 대리 웹표준이냐 속도냐 (UI 개발자의 고뇌 ) RIA 오창훈 대리 GS 이숍만의 RIA 개발활용팁과 노하우 프로젝트 김현 과장 효율적인 유지보수를 위한 개발 및 관리 프레임워크 추경돈 대리 Spring Framework 도입 사례 SE 김풍주 대리 웹 표준스펙 살펴보기 ( 명세서에 살고 명세서에 죽다 ) 쇼핑몰 트렌드 초청 김태진 쇼핑몰 컨설턴트가 바라본 쇼핑몰 트렌드 코드관리 허광남 과장 레거시 코드 관리 전략 ( 남이 짠 코드 빨리 알아보기 ) SQL 튜닝 박광일 대리 웹개발자의 약한고리 SQL 뛰어넘기
  2. 2. 웹개발자의 약한고리 SQL 뛰어넘기 박 광 일
  3. 3. 안갯속 상황 ! /18 <ul><li>12 월 19 일 대통령 선거 </li></ul><ul><li>BBK 김경준 </li></ul><ul><li>이명박 , 이회창 , 정동현 , 문국현 … 12 명의 출사표 </li></ul><ul><li>000 무혐의 결론 ? </li></ul>
  4. 4. 복잡한 JAVA vs SQL /18 복잡한 JAVA 복잡한 SQL 길을 잃어 버린 개발자 ..
  5. 5. 단순한 SQL /18 SELECT * FROM EC_PRD A WHERE TO_CHAR(CREDATE,'YYYMMDD') < '20071110' AND PRDID = 2398308 * INDEX : EC_PRD_PRDID_IX : PRDID+ CREDATE * EC_PRD : CREDATE DATE NOT NULL EXECUTION PLAN -------------------------------------------------------------- SELECT STATEMENT Optimizer=RULE - TABLE ACCESS(FULL) OF ‘ EC_PRD ’ (COST=120 Card=22 Bytes=240K) <ul><li>변경 전 </li></ul>SELECT * FROM EC_PRD A WHERE PRDID = 2398308 AND CREDATE < TO_DATE( ‘ 20071110 ‘ , ’ YYYMMDD ’ ) EXECUTION PLAN -------------------------------------------------------------- SELECT STATEMENT Optimizer=RULE (Cost=3 Card=1 Bytes=2K) - TABLE ACCESS (BY INDEX ROWID) OF 'EC_PRD' (Cost=3 Card=1 Bytes=2K) -INDEX (RANGE SCAN) OF ' EC_PRD_PRDID_IX ' (UNIQUE) (Cost=2 Card=18) <ul><li>변경 후 ( 기본적으로 DATA TYPE 과 INDEX 를 고려하지 않은 문제점 개선 ) </li></ul>DATA TYPE 과 INDEX
  6. 6. DATA TYPE /18 암시적 (Implicit) 데이터 유형 변환 명시적 (Explicit) 데이터 유형 변환 데이터 유형 변환 암시적 변환의 위험성 SQL> DESC EMP2 Name Null? Type ------------------------------------------- EMPNO NOT NULL VARCHAR2(4) ENAME VARCHAR2(10) JOB VARCHAR2(9) HIREDATE DATE SAL NUMBER(7,2) DEPTNO NUMBER(2) SQL>SELECT * FROM EMP2 WHERE empno=1234;  TO_NUMBER(empno)=1234 EMPN ENAME JOB HIREDATE SAL DEPTNO ---- -------- ------- -------------------- -------- --------- 7369 SMITH CLERK 1980-12-17 00:00:00 800 20 Execution Plan ---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=CHOOSE 1 0 TABLE ACCESS (FULL) OF 'EMP2 ' SQL> SELECT * FROM EMP2 WHERE empno=‘1234’; Execution Plan ---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=CHOOSE 1 0 TABLE ACCESS (BY INDEX ROWID) OF 'EMP2' 2 1 INDEX (RANGE SCAN) OF 'EMP2_EMPNO_IDX' (NON-UNIQUE)
  7. 7. 좌절의 원인 /18 단 1 패가 모든 운명을 결정 ! 항우 (69 승 1 패 ) 유방 (69 패 1 승 ) VS JAVA 69 개 잘 짜고 1 개의 SQL 이 무너지면 전체에 영향을 준다 !
  8. 8. SQL 작성 방법 /18 + 성능 고려한 SQL 작성
  9. 9. SQL 을 위한 Oracle 구조의 이해 /18 Client Process SERVER Process SGA(System Global Area) Buffer Cache PGA Memory ④ Physical Reads physical writes physical reads direct physical writes direct ① SQL DBWR ③ Logical Reads Shared Pool ② Parse Log Buffer 서버 프로세스별 시간 환산 DISK * 데이터 1 개 블록 (8Kbyte) 읽을 때 켁 ! 7.7 개월 Cache ① Register ② L1/L2 ③ Memory ④ Disk Access Time 3ns 10ns 450ns 20ms Second 3 초 10 초 7.5 분 ?
  10. 10. INDEX /18 TABLE (EMP) EMPNO ENAME JOB 7654 강감찬 부장 7900 류관순 과장 7689 황진이 과장 7499 이순신 차장 7934 변강쇠 부장 7844 조자룡 차장 7369 안중근 상무 7839 장보고 과장 7531 신윤복 차장 7856 홍길동 과장 7432 김유신 부장 7827 김두환 부장 INDEX (EMP_JOB_IDX) INDEX-KEY ROWID 과장 0000A95B.0002.0001 과장 0000A95B.0005.0001 과장 0000E62E.0009.0001 과장 0000E9BE.0002.0001 부장 000062BE.0001.0001 부장 000062BE.0003.0001 부장 000093A6.0005.0001 부장 000093B2.000B.0001 상무 000069C5.0001.0001 차장 0000E9BE.0002.0001 차장 0000E9BE.0005.0001 차장 0000E9BE.000B.0001 <ul><li>인덱스는 테이블의 ROW 와 하나씩 대응되는 별도의 객체 인덱스를 생성시킨 KEY COLUMN + ROWID 구성되어 정렬된 상태 </li></ul>INDEX 구조 <ul><li>INDEX 특징 </li></ul><ul><li>튜닝의 가장 중요한 Point </li></ul><ul><li>OPTIMIZER 가 실행계획 (PLAN) 을 만드는 가장 중요한 판단 기준 </li></ul><ul><li>인덱스의 ROWID 를 통해 가장 빠른 액세스 경로를 가짐 </li></ul><ul><li>대표 키 값을 통해 미리 정렬된 인덱스 만을 검색하여 해당 Row 만 바로 액세스 </li></ul><ul><li>최소한의 데이터 블록 읽기를 통한 성능 향상시킬 수 있음 </li></ul><ul><li>적절한 인덱스의 조정만으로도 액세스의 효율성을 크게 향상 </li></ul>INDEX, PLAN, TKPROF ^
  11. 11. INDEX /18 INDEX 를 사용할 수 없는 경우 INDEX, PLAN, TKPROF ^ 종류 원본 구문 변형 제거 1. 외부적변형 SELECT * FROM EMP WHERE SUBSTR(DNAME,1,3) = 'ABC' SELECT * FROM EMP WHERE DNAME LIKE 'ABC%' 2. 내부적변형 SELECT * FROM SAMPLET WHERE CHA = 10 => TO_NUMBER(CHA) = 10 SELECT * FROM SAMPLET WHERE CHA = ’ 10 ’ 3. 부정형비교 SELECT 'Not found !' INTO :COL1 FROM EMP WHERE EMPNO <> '1234' SELECT ’ Not found' INTO :COL1 FROM DUAL WHERE NOT EXISTS ( SELECT '' FROM EMP WHERE EMPNO = '1234') 4.NULL 비교 SELECT * FROM EMP WHERE ENAME IS NOT NULL SELECT * FROM EMP WHERE ENAME > ' ‘ /* SPACE */
  12. 12. INDEX – HINT <ul><li>HINT (OPTIMIZER HINT ) 의 종류 </li></ul><ul><li>- OPTIMIZER 가 최적의 실행 계획을 생성하는데 도움을 주는 것 => 훈수 </li></ul>/18 INDEX, PLAN, TKPROF ^ Access Methods Hints INDEX, NO_INDEX INDEX_FFS INDEX_ASC, INDEX_DESC USE_CONCAT FULL HASH JOIN 순서를 결정 Hints ORDERED STAR JOIN Operation 결정 Hints LEADING USE_NL USE_MERGE USE_HASH Optimization Goals and Approaches ALL_ROWS FIRST_ROWS CHOOSE RULE Parallel Execution Hints PARALLEL, NOPARALLEL PARALLEL_INDEX
  13. 13. RBO vs CBO /18 Oracle 9i 10g ... 11g Rule Based Optimizer Cost Based Optimizer 통계정보 자동생성 ANSI 1999 표준 SQL RBO 지원 중지 Oracle 이 많은 것을 해 주려 하지만 .. 개발자의 머리와 실력을 믿는다 . Cost Based Optimizer
  14. 14. Red Color 는 선정적이다 ! /18 중요한 정보를 말해주고 있다 ! INDEX, PLAN, TKPROF ^
  15. 15. PLAN PLAN PLAN /18 1. 문제 가 있다 ! 라는 것을 알 / 아 / 야 한다 ! 2. Plan 을 이해해야 한다 ! INDEX, PLAN, TKPROF ^
  16. 16. PLAN PLAN PLAN <ul><li>PLAN 을 보는 방법 </li></ul><ul><ul><li>위에서 아래방향으로 </li></ul></ul><ul><ul><li>안에서 밖으로 </li></ul></ul><ul><ul><li>JOIN 은 PAIR 로 , JOIN 순서 & 방법은 각 Operation 대로 확인 </li></ul></ul>/18 SELECT ename, job, sal, dname FROM emp, dept WHERE emp.deptno = dept.deptno AND not exists (SELECT * FROM salgrade WHERE emp.sal BETWEEN losal AND hisal) 1 2 6 FILTER NESTED LOOPS TABLE ACCESS (FULL) salgrade 3 4 TABLE ACCESS (FULL) emp TABLE ACCESS (BY ROWID) dept 5 INDEX (UNIQUE SCAN) pk_dept <ul><li>1 FILTER </li></ul><ul><li>NESTED LOOPS </li></ul><ul><li>TABLE ACCESS FULL EMP </li></ul><ul><li>TABLE ACCESS BY ROWID DEPT </li></ul><ul><li>INDEX UNIQUE SCAN PK_DEPT </li></ul><ul><li>TABLE ACCESS FULL SALGRADE </li></ul>① 구문 ② 실행 계획 ③ 실행 계획 분석 순서 INDEX, PLAN, TKPROF ^
  17. 17. TKPROF (Trace) <ul><li>SQL Trace 및 TKPROF 예제 </li></ul>/18 AUTOTRACE 예제 SQL> set autotrace traceonly statistics SQL> SELECT * 2 FROM products 3 WHERE prod_category = 'Men' 4 AND prod_subcategory = 'Jeans - Men'; 333 개의 행이 선택되었습니다 . Statistics ------------------------------------------ 0 recursive calls 0 db block gets 159 consistent gets 139 physical reads 0 redo size 38034 bytes sent via SQL*Net to client 745 bytes received via SQL*Net from client 24 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 333 rows processed INDEX, PLAN, TKPROF ^ Memory Disk <ul><li>recursive call : 이미 Parsing 된 것이 메모리에 있음 </li></ul><ul><li>db block gets : 내가 update 하고 commit 안 한 것 </li></ul><ul><li>consistent gets : 다른 User 가 Update 한 Column 존재 </li></ul><ul><li>physical reads : 디스크에서 139 개 블록을 읽음 </li></ul>
  18. 18. TKPROF (Trace) <ul><li>SQL Trace 및 TKPROF 예제 </li></ul>/18 SELECT * FROM products WHERE prod_category = 'Men' AND prod_subcategory = 'Jeans - Men' Call Count CPU Time Elapsed Time Disk Query Current Rows ------ ----- -------- ------------ ---------- ---------- ---------- Parse 1 0.000 0.022 0 0 0 0 Execute 1 0.000 0.040 0 0 0 0 Fetch 35 0.030 0.298 139 159 0 333 ------ ------ -------- ------------ ---------- ---------- ---------- Total 37 0.030 0.360 139 159 0 333 Elapsed Time for Client(sec.): 0.402 Misses in library cache during parse: 1 Optimizer goal: CHOOSE Parsing user: SH (ID=49) Rows Row Source Operation ------- --------------------------------------------------- 0 STATEMENT 333 TABLE ACCESS BY INDEX ROWID PRODUCTS (cr=159 r=139 w=0 time=295493 us) 333 BITMAP CONVERSION TO ROWIDS (cr=11 r=11 w=0 time=168426 us) 1 BITMAP AND (cr=11 r=11 w=0 time=167759 us) 1 BITMAP CONVERSION FROM ROWIDS (cr=3 r=3 w=0 time=122495 us) 333 INDEX RANGE SCAN PRODUCTS_PROD_SUBCAT_IX (cr=3 r=3 w=0 time=111775 us)OF PRODUCTS_PROD_SUBCAT_IX (NONUNIQUE) 1 BITMAP CONVERSION FROM ROWIDS (cr=8 r=8 w=0 time=30264 us) 2594 INDEX RANGE SCAN PRODUCTS_PROD_CAT_IX (cr=8 r=8 w=0 time=25484 us)OF PRODUCTS_PROD_CAT_IX (NONUNIQUE) Elapsed Time: 작업의 시작부터 종료까지 걸리는 시간 Query : 데이터 블록을 읽은 수 INDEX, PLAN, TKPROF ^ 의미 있는 숫자들 cr : Consistent Read 총 블록수 - Memory r : Physical Read 총 블록수 (10g pr) – Disk Read w : Physical Write 총블록수 (10g pw) – Disk Write
  19. 19. 죽어서도 살아서도 아름다운 개발자로 ! 죽어서 살 것인가 ! 살아서 죽을 것인가 ! 죽어서 아름다울 것인가 ! 살아서 더러울 것인가 ! 김훈 ‘남한산성’ 中 출처 : SLRCLUB - 영원한 7 모석  

×