레이블이 오라클자바커뮤니티인 게시물을 표시합니다. 모든 게시물 표시
레이블이 오라클자바커뮤니티인 게시물을 표시합니다. 모든 게시물 표시

2013년 10월 23일 수요일

오라클 SQL 튜닝의 도구 – SQL*TRACE와 TKPROF [ORACLE강좌]

오라클  SQL 튜닝의 도구 – SQL*TRACE와 TKPROF [ORACLE강좌]

Oracle의 SQL*TRACE는 사용자가 실행 한 SQL문에 대해 구문분석(Parsing), 실행(execute), 추출(fetch) 부분으로 나누어 각 단계에서 걸리는 Overhead와 시간 등의 통계 정보를 일정한 형태로 저장 합니다. EXPALIN PLAN에서 제공하는 정보와 더블어 CPU/IO의 필요량, 실행계획의 각 단계에서의 레코드 개수등의 정보도 확인 가능 합니다. EXPLAIN PLAN 명령어와 함께 자주 사용되는 튜닝의 도구 입니다. 

SQL*TRACE나 TKPROF를 실행 했을 때의 결과는 이해하기가 쉽지 않지만 강력한 튜닝의 도구 입니다. SQL*TRACE에 의해 분석되는 결과는 바이너리 형태로 운영체제의 파일 시스템에 생성 됩니다. 물론 바이너리 이므로 결과를 직접 눈으로 보면 이해가 되지 않지만 TKPROF 유틸리티를 이용하여 텍스트 파일 형태로 변환 시켜 확인이 가능 합니다. 

SQL*TRACE의 결과는 데이터베이스 전체 또는 특정 세션에 대해 적용 할 수 있는데 데이터베이스 전체에 트레이스를 적용하면 실제 Application 수행에 추가적인 부하를 가져오므로 특별한 경우를 제외하고 전체 데이터베이스 시스템에 TRACE를 거는 것은 삼가 해야 합니다. 대부분은 특정 세션에 대해서만 부분적으로 활성화 하여 사용 합니다. 


SQL*TRACE의 사용 

SQL TRACE를 사용하기 전에 몇 가지 설정이 필요한데 먼저 초기파일에서 USER_DUMP_DEST 파라미터를 확인해야 합니다. 이 매개변수는 TRACE를 실행 할 때 생성되는 파일의 위치를 설정 하는 것입니다. 또한 시간 정보를 TRACE 항목에 추가할려면 TIMED_STATISTICS 항목을 TRUE로 해야 하거나 SQL*Plus등에서는 alter session set timed_statistics=true 라고 해주어야 합니다. 아래에 자세히 확인 하도록 합니다. 

TIMED_STATISTICS 

시간 통계 정보에 대해 수집여부를 결정, 기본값은 false 
세션레벨에서는 alter session set timed_statistics=true라고 하면 됩니다. 

MAX_DUMP_FILE_SIZE 

TRACE의 결과로 생기는 바이너리 파일의 최대 사이즈를 단위는 블록 입니다. 기본값은 500 블록 입니다. 또한 세션 레벨에서 다음과 같이 지정 가능 합니다. Alter session set max_dump_file_size = 800(800개의 시스템 블록) 

USER_DUMP_DEST 

TRACE의 결과로 생기는 바이너리 파일의 위치를 지정 합니다. 세션레벨에서는 alter session set  user_dump_dest = “C:\oracle\admin\wink\udump” 등으로 지정 합니다. 

위의 세개의 파라미터를 init.ora 파일에 지정하였다면 SQL*TRACE의 시작을 전체 데이터베이스에서 할건지 세션 레벨에서 할건지를 정할 수가 있습니다. 인스턴스 레벨에서 할려면 init.ora 파일에서 SQL_TRACE 항목을 TRUE로 설정하면 되구요 세션 레벨에서 할려면 alter session set sql_trace = true 라고 하면 됩니다. 

자 이제 실습을 위해 위의 3개의 매개변수를 init.ora 에 설정토록 합니다. 

MAX_DUMP_SIZE = 800 
TIMED_STATISTICS = TRUE 
USER_DUMP_DEST = C:\oracle\admin\wink\udump 

다음을 따라 하도록 합니다. 

SQL> conn / as sysdba 
연결되었습니다. 
SQL> shutdown immediate 
데이터베이스가 닫혔습니다. 
데이터베이스가 마운트 해제되었습니다. 
ORACLE 인스턴스가 종료되었습니다. 
SQL> startup open 
ORACLE 인스턴스가 시작되었습니다. 

Total System Global Area 135338868 bytes 
Fixed Size 453492 bytes 
Variable Size 109051904 bytes 
Database Buffers 25165824 bytes 
Redo Buffers 667648 bytes 
데이터베이스가 마운트되었습니다. 
데이터베이스가 열렸습니다. 

SQL>conn scott/tiger 

SQL> alter session set sql_trace=true; 

세션이 변경되었습니다. 

SQL> select job,avg(sal) from emp 
2 group by job 
3 having avg(sal) > (select avg(sal) from emp 
4 where job = 'SALESMAN'); 

JOB AVG(SAL) 
--------- ---------- 
ANALYST 3000 
MANAGER 2758.33333 
PRESIDENT 5000 

session에서 trace를 중지 

SQL> alter session set sql_trace=false; 

SQL*Plus를 종료하고 c:\oracle\admin\wink\udump에 가보면 trc 파일이 생겼을 것 
입니다. 저의 경우 DB SID가 wink이므로 wink_ora_3316.trc 와 같은 파일이 생겼습니다. 

TKPROF를 이용하여 TRACE파일을 텍스트 파일로 변경 하기 

TKPROF Utility를 이용하면 매우 유용한 분석 정보를 얻을 수 있습니다. 즉 TKPROF의 결과 파일은 트레이스가 실행되는 동안 프로세스에 의해 데이터베이스에서 실행된 작업에 대한 요약 정보 입니다. 

텍스트 파일의 내용을 보면 PARSE, EXECUTION, FETCH시 작업을 실행 한 횟수, CPU 사용 시간, 검색된 행이 무엇인지, SQL이 수행된 총 소요시간, DISK IO 블록 수, 조건을 만족하는 전체 행의 수, 수행된 SQL문이 사용한 SGA 영역의 크기, SQL문장의 실행 계획, 해당 세션에서 작업했던 전체 작업에 대한 CPU, 메모리, 블록의 크기 등의 정보를 확인 할 수 있습니다. 

SQL문을 해석하기 위해서는 아래의 단계가 필요 합니다. 

파싱(parse) 

SQL문을 실행 계획으로 번역 하는 것을 말합니다. 해당 SQL을 실행 하는데 필요한 적절한 권한, 컬럼이 있는지, 참조된 객체에 관한 확인 등의 작업이 이루어지게 됩니다. 

실행(execution) 

오라클에 의해 SQL문을 실제 실행 한 것을 말합니다. 

추출/인출(fetch) 

쿼리에 의해 추출된 레코드를 이여기 합니다. Select 문에서만 이용 됩니다. 


다음은 TKPROF의 통계 정보 컬럼 입니다. 

Count : 분석, 실행, 추출을 몇번 했는지를 나타 냅니다. 
CPU : 분석, 실행, 추출에 대한 CPU 처리 시간(CURSOR를 공유하면 분석단계의 처리 시간은 0 입니다.) 
Elapsed : 분석, 실행, 추출 처리 단계별로 처리된 소요 시간 
Disk : 테이블의 데이터를 읽기 위해 데이터 파일로부터 읽어 들인 블록 수 
Query : SELECT로 데이터를 읽어 올 때 이미 다른 사용자에 의해 같은 데이터가 사용 되었다면 그 블록에서 데이터를 가져옵니다. 
Current : 메모리에 저장된 데이터를 가지고 오기 위해 읽은 버퍼의 블록 수(update, insert, delete 후 select 했을 때) 

TKPROF를 실행하기 위한 문법 

Explain = 사용자계정/패스워드(명시된 사용자에 대해 EXPLAIN PLAN 실행) 
Print = n (트레이스 파일내의 분석된 SQL문의 수를 n 만큼만 제한할 때 이용) 
Record = 파일명(트레이스 파일내에 분석된 SQL문을 지정한 파일에 저장) 
Sort=option(트레이스 파일내에 분석된 SQL문을 지정한 옵션에 의해 정렬) 
Sys=[NO](트레이스 파일내에 생성된 SQL 문장 중에 오라클 서버가 내부적인 작업을 위해 실행한 SQL문장을 출력 시 포함 할건지를 결정) 
Table=스키마.테이블명(실행 계획을 지정한 테이블에 저장) 

이전의 SQL*TRACE에 의해 생긴 바이너리 파일을 TKPROF를 이용하여 분석을 해보도록 하겠습니다. 

명령프롬픝에서 다음과 같이 실행 합니다.(TRACE 파일이 만들어진 곳에서 실행) 

C:\oracle\admin\wink\udump>tkprof wink_ora_3316.trc sql1.tkp sys=no explain=scot 
t/tiger 

TKPROF: Release 9.2.0.1.0 - Production on 목 Dec 16 01:33:23 2004 

Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved. 

다음은 sql1.tkp 파일의 내용 입니다. 



TKPROF: Release 9.2.0.1.0 - Production on 목 Dec 16 01:33:23 2004 

Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved. 

Trace file: wink_ora_3316.trc 
Sort options: default 

******************************************************************************** 
count = number of times OCI procedure was executed 
cpu = cpu time in seconds executing 
elapsed = elapsed time in seconds executing 
disk = number of physical reads of buffers from disk 
query = number of buffers gotten for consistent read 
current = number of buffers gotten in current mode (usually for update) 
rows = number of rows processed by the fetch or execute call 
******************************************************************************** 

alter session set sql_trace=true 


call count cpu elapsed disk query current rows 
------- ------ -------- ---------- ---------- ---------- ---------- ---------- 
Parse 0 0.00 0.00 0 0 0 0 
Execute 1 0.00 0.00 0 0 0 0 
Fetch 0 0.00 0.00 0 0 0 0 
------- ------ -------- ---------- ---------- ---------- ---------- ---------- 
total 1 0.00 0.00 0 0 0 0 

Misses in library cache during parse: 0 
Optimizer goal: CHOOSE 
Parsing user id: 59 (SCOTT) 
******************************************************************************** 


아래는 사용자가 실행한 SQL 문장 입니다. 

select job,avg(sal) from emp 
group by job 
having avg(sal) > (select avg(sal) from emp 
where job = 'SALESMAN') 

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.00 0 6 0 3 
------- ------ -------- ---------- ---------- ---------- ---------- ---------- 
total 4 0.00 0.01 0 6 0 3 

Misses in library cache during parse: 1 이 값이 0이라는 의미는 실행한 SQL문이 이전에 실행 된적이 없었음을 나타 냅니다. 
Optimizer goal: CHOOSE 옵티마이저 모드 입니다. 
Parsing user id: 59 (SCOTT) 

Rows Row Source Operation 
------- --------------------------------------------------- 
3 FILTER 
5 SORT GROUP BY 
14 TABLE ACCESS FULL EMP 
1 SORT AGGREGATE 
4 TABLE ACCESS FULL EMP 


Rows Execution Plan 
------- --------------------------------------------------- 
0 SELECT STATEMENT GOAL: CHOOSE 
3 FILTER 
5 SORT (GROUP BY) 
14 TABLE ACCESS GOAL: ANALYZED (FULL) OF 'EMP' 
1 SORT (AGGREGATE) 
4 TABLE ACCESS GOAL: ANALYZED (FULL) OF 'EMP' 

******************************************************************************** 

alter session set sql_trace=false 


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

Misses in library cache during parse: 0 
Optimizer goal: CHOOSE 
Parsing user id: 59 (SCOTT) 



******************************************************************************** 
아래의 TOTAL은 전체 작업 결과에 대한 분석 결과 입니다. 

OVERALL TOTALS FOR ALL NON-RECURSIVE STATEMENTS 

call count cpu elapsed disk query current rows 
------- ------ -------- ---------- ---------- ---------- ---------- ---------- 
Parse 2 0.00 0.00 0 0 0 0 
Execute 3 0.01 0.00 0 0 0 0 
Fetch 2 0.00 0.00 0 6 0 3 
------- ------ -------- ---------- ---------- ---------- ---------- ---------- 
total 7 0.01 0.01 0 6 0 3 

Misses in library cache during parse: 1 


OVERALL TOTALS FOR ALL RECURSIVE STATEMENTS 

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 1 0.01 0.00 0 3 0 1 
------- ------ -------- ---------- ---------- ---------- ---------- ---------- 
total 3 0.01 0.00 0 3 0 1 

Misses in library cache during parse: 0 

3 user SQL statements in session. 
1 internal SQL statements in session. 
4 SQL statements in session. 
1 statement EXPLAINed in this session. 
******************************************************************************** 
Trace file: wink_ora_3316.trc 
Trace file compatibility: 9.00.01 
Sort options: default 

1 session in tracefile. 
3 user SQL statements in trace file. 
1 internal SQL statements in trace file. 
4 SQL statements in trace file. 
4 unique SQL statements in trace file. 
1 SQL statements EXPLAINed using schema: 
SCOTT.prof$plan_table 
Default table was used. 
Table was created. 
Table was dropped. 
54 lines in trace file. 

2013년 10월 17일 목요일

오라클 ORACLE 인덱스가 없는 테이블 조회 SQL

오라클  ORACLE 인덱스가 없는 테이블 조회 SQL 

참고하세요`

select        OWNER, 
        TABLE_NAME 
from 

select        OWNER, 
        TABLE_NAME 
from        dba_tables 
minus 
select        TABLE_OWNER, 
        TABLE_NAME 
from        dba_indexes 

orasnap_noindex 
where        OWNER not in ('SYS','SYSTEM') 
order        by OWNER,TABLE_NAME 

오라클자바커뮤니티에서 설립한 개발자교육6년차 오엔제이프로그래밍 실무교육센터(오라클SQL,튜닝,힌트,자바프레임워크,안드로이드,아이폰,닷넷 실무개발강의)  


2013년 8월 9일 금요일

오라클의 각 Table은 내부적으로 ROWID 라는 의사 열을 가진다. 보통 SELECT등으로 Table을 질의하면 출력되지 않으나 컬럼 명으로 ROWID라는 예약어를 사용하면 읽어 들일 수 있다.  

오라클자바커뮤니티에서 설립한 오엔제이프로그래밍 실무교육센터
(오라클SQL, 튜닝, 힌트,자바프레임워크, 안드로이드, 아이폰, 닷넷 실무전문 강의)  


ROWID에는 Table의 각 행에 대해 물리적인 주소라고 이해 하면 될 것이다. 오라클7에서 ROWID에는 파일번호, 블록번호, 블록 내 ROW번호 3가지 정보를 가지고 있었지만 오라클8 이상부터 ROWID에는 객체의 고유번호를 포함하고 있다는 것은 참고로 알아두자. 데이터를 검색할 때 ROWID를 이용하여 검색 한 다면 가장 빨리 원하는 자료를 검색하는 것이 가능하다.
아래를 보면 앞의 중복된 데이터를 지우는 질의가 이해 될 것이다. 같은 주민등록번호 와 이름을 가지더라도 rowid는 틀리다. 이 특징을 이용하여 중복 데이터를 찾는 것이다.

SQL> select rowid, jumin, name from addrbook;
ROWID              JUMIN          NAME
------------------ -------------- ------------
AAAJMZAABAAAPEKAAA 111111-2222222 홍길동
AAAJMZAABAAAPEKAAB 333333-4444444 가길동
AAAJMZAABAAAPEKAAC 111111-2222222 홍길동

2013년 8월 8일 목요일

자바의 연산자

이번 강좌에서는 자바에서의 연산자를 배워보도록 하겠습니다.

대부분 언어를 공부해 보신 분들은 수도 없이 많이 보셨던 부분입니다. 잘 모르셔도 됩니다. 뒤에 공부하시다 보면 저절로 아시는 것도 있을 것이며 나중에 원하는 일을 하시다가 다시 아시게 되는 경우도 있을 겁니다. 그러나 기본이 없으면 오래가지 못합니다. 간단히 공부해 두시기 바랍니다.



자바에서 연산자는

산술연산자(Arithmetic Operator) --> 단항연산자(++,--), 이항연산자(+,-,*,/)

관계연산자(Relational Operator) -->>, >=, <, ><=, ==, != >

논리연산자(Logical Operator) -->&&, ||, &, |, !

비트연산자(Bitwise Operator) -->&, |, ^, ~, >>, >>>, <><

조건연산자(Conditional Operator) --> ?(삼항연산자)

할당연산자(Assignment Operator) --> +=, -=, *=, /=, &=, ^=, |=, <><=, >>=, >>>=

등으로 나누어 볼 수 있습니다.



연산자의 우선 순위는 괄호를 치시면 되니까 별다르게 고려 하지 않겠습니다.



1. ++, --, !, ~, instanceof

단항 연산자이다.
! : 논리형 자료형(boolean)의 부정
~ : 정수형 자료에 대한 보수 연산
++, -- : 단항 연산자, 변수의 앞쪽에 붙는 경우와 뒤쪽에 붙는 경우의 동작 형태가 다르다.
앞에 붙은 경우 : 연산이 수행된 다음 값
뒤에 붙는 경우 : 연산이 수행되기 전의 값



아래의 예제를 실습해 보세요~

[예제]

public class Op1 {
public static void main(String[] args) {
int a = 8;
//이진수 형태로 출력 합니다.(0이 아닌것 부터 출력)
System.out.println(Integer.toBinaryString(a));
a= ~a; //보수 연산, 1은0으로 0은 1로
System.out.println(Integer.toBinaryString(a));

a = 8;
a = a++;
System.out.println("a = " +a);

a = a++ +1;
System.out.println("a++ +1 = " +a);

}
}




[결과]

1000(앞 부분에 있는 0000~ 은 출력하지 않는다...)
11111111111111111111111111110111
a = 8
a++ +1 = 9



2. <><, >>, >>>

비트연산에 관련된 연산자(Shift 연산자) 입니다.
<>< 연산자는 좌측 쉬프트 이므로 2를 곱하는 효과가 있습니다.
>> 연산자는 우측 쉬프트 이므로 2로 나누는 효과가 있습니다.
<><, >> 연산자인 경우 부호를 고려 한다는것을 명심하세요~
당연히 부호를 고려하므로 왼쪽을 해당 부호 비트로 채웁니다.

>>> 연산자인 경우 왼쪽을 0으로 채웁니다. 부호를 고려하지 않습니다.
양수인 경우 >>, >>> 연산자는 같은 효과 이지만 음수인 경우 다른 결과가 나타 납니다.

[예제]

public class ShiftTest {
public static void main(String[] args) {
int a=-64;
System.out.println("<><");
System.out.println(Integer.toBinaryString(a));
System.out.println(Integer.toBinaryString(a<><1));
System.out.println(Integer.toBinaryString(a<><2));
System.out.println(">>");
System.out.println(Integer.toBinaryString(a));
System.out.println(Integer.toBinaryString(a>>1));
System.out.println(Integer.toBinaryString(a>>2));
System.out.println(">>>");
System.out.println(Integer.toBinaryString(a));
System.out.println(Integer.toBinaryString(a>>>1));
System.out.println(Integer.toBinaryString(a>>>2));
}
}



[결과]

<><
11111111111111111111111111000000
11111111111111111111111110000000
11111111111111111111111100000000
>>
11111111111111111111111111000000
11111111111111111111111111100000
11111111111111111111111111110000
>>>
11111111111111111111111111000000
1111111111111111111111111100000
111111111111111111111111110000



3.<, >, >=, <=, ==, !=

관계 연산자들 이며 연산의 결과로 boolean 값을 리턴 합니다.
이 연산자의 대상은 기본형 데이터에 한정되며 객체에 대해서는 쓰이지 못 합니다.
예)System.out.println(5 > 7);
==, != 또한 관계 연산자 이나 위의 것 보다 우선 순위가 낮다. 연산자의 두 항이 같은지 다른지에 따라 boolean 값을 돌려 줍니다.
==, != 연산자는 객체에 대해 사용이 가능한데 그 기준은 객체가 같은 메모리 영역에 있는지 아닌지로서 평가 합니다.



4.&, ^, |, &&, ||

& : 비트 AND
^ : 비트 XOR
| : 비트 OR
&& : ‘&’와 같이 AND 연산을 하지만 대상은 boolean
|| : ‘|’와 같이 OR 연산을 하지만 대상은 boolean



5. ?

조건연산자 이며 형식은 아래와 같습니다.
형식 : (조건) ? (참 일때의 식) : (거짓 일때의 식)
if 문등을 몇줄에 걸쳐 써야 하는것을 간략하게 기술 할 수 있도록 해 줍니다.
[예]
int i=2;
int result = i<5 ? i+10 : i/2; >
System.out.println(result);



6. =, op=

할당 연산자 이며 우선 순위가 가장 낮습니다.
Op= 연산자는 다음과 같은 것들이 있습니다.
+=, -=, *=, /=, &=, ^=, |=, <><=, >>=, >>>=

오라클자바커뮤니티에서 설립한 오엔제이프로그래밍 실무교육센터, iPhone 하이브리드 앱 개발 실무과정(평일야간) 개강확정

iPhone 하이브리드 앱 개발 실무과정

오라클자바커뮤니티에서 설립한 오엔제이프로그래밍 실무교육센터
(오라클SQL, 튜닝, 힌트,자바프레임워크, 안드로이드, 아이폰, 닷넷 실무전문 강의)  

강좌명iPhone 하이브리드 앱 개발 실무과정(평일야간)
교재본원 자체교재 무료지원
강좌 일정08월21일(수) ~ 09월09일(월)((평일야간) 19:00~22:00, 14일) 총 42시간
강의 장소[B강의장]구로디지털단지역2번 출구-> 미니스톱끼고 우회전 -> 100m 직진 후 골목길 끝에서 이마트방향 우회전 -> 50m 직진 후 우체국 옆골목으로 길건너서 직진 -> 150미터 직진 후 JnK 타워에서 우회전 -> 50미터 직진 후 우측에 코오롱빌란트2차 803호 (구로구 구로3동 222-8 코오롱디지털타워 빌란트2차 803호)
[약도보기]
수강절차- 강좌내용 확인
- 전화 또는 홈페이지(www.onjprogramming.co.kr)를 통한 수강지원 및 수강료 결제(무통장입금, 온라인 카드결제)
- 고용보험 가입자(재직자)인 경우 고용보험환급 관련 서류 제출
- 수강전 : 커리큘럼 및 장소에 대해 다시 한번 공지
- 교육 전 설문 작성(간단한 개발 경력, 수강 목적, 강좌진행방식 등)
- 강좌 수강
- 수강후 : 교육 후 설문 작성
수강료580,000원
- 맥북무료지원
고용보험 환급(50~80% 환급)
[고용주환급]대기업:17만원 전후,중소기업:216,968원
[개인수강지원(개인환급)]정규직 464,000원 ,비정규직:전액환급

재직자 내일배움카드 : 정부지원금 80% 자기부담금 20%
(구 능력개발카드 명칭이 내일배움카드로 변경 / 연간 총한도 200만원)

* 휴강 :법정공휴일
수강료
입금안내
- 온/오프라인 카드결제, 계좌이체(수강안내->입금안내 참조)
문의사항02-851-4790 번으로 연락 부탁 드립니다.
교육개요본강좌는 아이폰과 아이팟 터치용 앱 개발을 위한 실용적인 경험을 제공하며. 쉽게 따라 해 볼 수 있도록 구성된 여러 샘플 예제를 통해서 Xcode 도구 사용법, 오브젝티브-C, 코어 프레임워크 등을 배우게 된다. 자신도 모르는 사이에 앱 개발에 필요한 기술은 물론이고 아이튠즈 앱스토어에 앱을 제출하는 과정도 알게 된다. 아이폰 프로그래밍에 첫 발을 내딛는 입문자 혹은 랭귀지 개발자에게 적합한 교육이다.

Xcode와 인터페이스 빌더 사용법, 오브젝티브-C를 이용한 모델-뷰-컨트롤러 구조, 데이터 입력 인터페이스 구현 및 입력 데이터 핸들링, 다양한 예제를 빌드를 통해 일반적으로 발생하는 문제 해결법, 앱스토어와 임시 배포에 필요한 요구 사항, 아이폰 가속도계, 근접 센서, 아이폰의 설정 앱 핸들링,이후 아이폰에서의 SQLite 활용, SQLite 관리 도구 활용, 실전에서 활용 가능한 최적화 기법 등의 내용을 배우게 됩니다.
교육목표- MAC 사용방법 실습
- Objective-C 프로그램 언어 이해
- Xcode와 인터페이스 빌더 사용법
- 오브젝티브-C를 이용한 모델-뷰-컨트롤러 구조 이해
- 데이터 입력 인터페이스 구현 및 입력 이헤
- 데이터 핸들링 이해
- 앱스토어와 임시 배포에 필요한 요구 사항
- UIKit프레임웍 이해
- 프로토콜, 델리게이트의 이해
- NSXMLParser
- 웹서버와 GET, POST 방식의 통신
- 임베디드 기기를 위한 SQLite 최적화
- SQLite 활용, SQLite 관리 도구 활용 이해
- SQLite 실전에서 활용 가능한 최적화 기법 이해
- 하이브리드앱 개발
교육대상-Objective-C 활용분야에 관심이 있는 자
-Cocoa / Xcode / iPhone 기반 애플리케이션/스마트폰 개발자
-SQLite 개발자
-SDK APP 개발자 
선수학습- c, c++
-프로그래밍 초보자
 



아이폰 개발 준비- MAC에 대한 개요와 이해
- MAC 사용방법 실습
- 개발자 라이센스 등록 절차 및 인증서 등록
- 앱의 다양한 배포방법(adHoc, Appstore, OTA)
objective-c- objective-c의 개요
- 콘솔창에서 클래스 만들고 gcc로 컴파일하기
- iPhone에 대한 개요과 구조 설명, Xcode 사용방법
- 메모리 관리(수동메모리관리)
- Foundation 프레임웍 개요
- UIKit프레임웍의 개요
- 세터와 게터 만들기
- 프로퍼티에 대한 이해, 점연산자
- 프로퍼티 속성
- 메시지 전달 방식에 대한 이해
- 프로토콜, 델리게이트의 이해 및 실습
iPhone SDK- Xcode에서 프로젝트 설정
- NSLog 및 출력 서식 사용하기
- 인터페이스 빌더, IBOutlet, IBAction에 대해 이해하기
- Immutable, Mutable 클래스의 차이
- MVC, Delegate, SingleTon, Target Action 패턴 이해
- 아이폰의 샌드박스구조에 대한 이해 및 파일처리
- UIButton, UILabel, UIImmageView 실습
- UISwitch, Webkit, UISegmetedControl 실습
- UITextField, UITextView, UISlider 실습
- main 구조파헤치기
- UIApplication 라이프 사이클 이해하기
- UIViewController , UIView 라이프 사이클 이해하기
- UIAlertView, UIActionSheet 실습
- UIPickerView 커스터마이징
- TableView 커스터마이징
- TableView Cell 커스터마이징
- UIKit Frameowork 와 Interface builder의 개연성 이해하기
- NSXMLParser
- 웹서버와 GET, POST 방식의 통신 구현
- Navigation Template 구현하기
- NSConnection을 이용한 ASynchronous 통신
SQLite3- Sqlite3 사용실습
- Sqlite3 사용실습
실무 하이브리드앱 개발- 하이브리드앱 개발
- 하이브리드앱 개발
- 하이브리드앱 개발
 

2013년 8월 3일 토요일

[Oracle Hint]ACCESS 경로를 변경하는 힌트(NO_EXPAND) , 오라클힌트강좌 CCESS 경로를 변경하는 힌트(NO_EXPAN)

[Hint]ACCESS 경로를 변경하는 힌트(NO_EXPAN)

NO_EXPAND 힌트는 CBO(COST BASED Optimizer) 모드에서 OR 조건이나 IN List등을 사용할 때 OR확장 (Concatenation등을)을 막는 것인데 실행 계획에 Concatenation등이 보이는 경우 이곳이 일어나지 않도록 처리해 줍니다.

구로디지털 오엔제이프로그래밍실무교육센터


OR UNION-ALL로 풀지 말고

아래의 예를 보죠~

[형식]

실습을 위해 먼저 옵티마이저 모드를 RULE로 바꾼 후

왜 바꾸냐 하면?  EMP 테이블의 경우 데이터 양이 적으므로 OR를 사용하더라도 FULL SCAN하는 실행계획을 만들어 내므로 고의로 CONCATENATION을 만들어 내기 위해 RULE BASED Optimizer Mode로 변경하는 것입니다. 물론 옵티마이저 모드를 CHOOSE로 한 후 테이블의 통계 정보를 삭제하는 경우에도 동일 합니다.

alter session set optimizer_mode=rule;

SELECT ename, sal
FROM   EMP
WHERE  JOB   = 'CLERK'
OR     JOB   = 'SALESMAN'

-----------------------------------------------------------------
Operation    Object Name  Rows   Bytes  Cost  
-----------------------------------------------------------------
SELECT STATEMENT Optimizer Mode=RULE                                
  CONCATENATION                                                 
    TABLE ACCESS BY INDEX ROWID   SCOTT.EMP                          
      INDEX <st1:placetype w:st="on">RANGE</st1:placetype> SCAN      SCOTT.IDX_EMP_JOB                         
    TABLE ACCESS BY INDEX ROWID   SCOTT.EMP                          
      INDEX <st1:placetype w:st="on">RANGE</st1:placetype> SCAN      SCOTT.IDX_EMP_JOB                         



SELECT
       ENAME, SAL
FROM   EMP
WHERE  JOB   = 'CLERK'
OR     JOB   = 'SALESMAN'

Operation            Object Name      Rows     Bytes    Cost     
SELECT STATEMENT Optimizer Mode=RULE                        6                        2            
  INLIST ITERATOR                                                                                     
    TABLE ACCESS BY INDEX ROWID         SCOTT.EMP        6           96         2            
      INDEX <st1:placetype w:st="on">RANGE</st1:placetype> SCAN             SCOTT.IDX_EMP_JOB      6                        1            




[실습]

-      실습을 위한 예제 테이블 및 데이터는 아래 링크에서 확인 바랍니다.

myemp1 : 1000만건
myemp1_old : 100만건
mydept : 5

테스트환경 : oracle 11g

아래와 같은 결과를 내기 위한 힌트 구문을 이해하고 왜 inlist iterator가 빠른지 느껴 보라.

먼저 인덱스를 하나 만들자.

SQL> create index idx_myemp1_sal on myemp1(sal);

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


n  옵티마이저가 사용 못하도록 일단 숨기고

SQL> alter index idx_myemp1_sal invisible;

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

n  인덱스가 없는 경우엔 무조건 FULL SCAN을 한다.


SQL> select count(*) from myemp1
  2  where sal = 100000
  3  or sal = 200000
  4  or sal = 300000;

  COUNT(*)
----------
        15

   : 00:00:08.85


-----------------------------------------------------------------------------
| Id  | Operation          | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |        |     1 |     5 | 17035   (2)| 00:03:25 |
|   1 |  SORT AGGREGATE    |        |     1 |     5 |            |          |
|*  2 |   TABLE ACCESS FULL| MYEMP1 |    15 |    75 | 17035   (2)| 00:03:25 |
-----------------------------------------------------------------------------

SQL> select count(*) from myemp1
  2  where sal = 100000
  3  or sal = 200000
  4  or sal = 300000;

  COUNT(*)
----------
        15

   : 00:00:08.82

Execution Plan
----------------------------------------------------------
Plan hash value: 3929728256

-------------------------------------
| Id  | Operation          | Name   |
-------------------------------------
|   0 | SELECT STATEMENT   |        |
|   1 |  SORT AGGREGATE    |        |
|*  2 |   TABLE ACCESS FULL| MYEMP1 |


n  인덱스를 다시 보이도록 하자.
SQL> alter index idx_myemp1_sal visible;

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

SQL> select /*+ index(myemp1 idx_myemp1_sal)  */ count(*) from myemp1
  2  where sal = 100000
  3  or sal = 200000
  4  or sal = 300000;

  COUNT(*)
----------
        15

   : 00:00:00.01

-------------------------------------------------------------------------------------
| Id  | Operation          | Name           | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |                |     1 |     5 |     5   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE    |                |     1 |     5 |            |          |
|   2 |   INLIST ITERATOR  |                |       |       |            |          |
|*  3 |    INDEX RANGE SCAN| IDX_MYEMP1_SAL |    15 |    75 |     5   (0)| 00:00:01 |
-------------------------------------------------------------------------------------

n  아래처럼 힌트를 안써도 CBO인 경우 알아서 인덱스를 사용한다.
SQL> select count(*) from myemp1
  2  where sal = 100000
  3  or sal = 200000
  4  or sal = 300000;

  COUNT(*)
----------
        15

   : 00:00:00.00

-------------------------------------------------------------------------------------
| Id  | Operation          | Name           | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |                |     1 |     5 |     5   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE    |                |     1 |     5 |            |          |
|   2 |   INLIST ITERATOR  |                |       |       |            |          |
|*  3 |    INDEX RANGE SCAN| IDX_MYEMP1_SAL |    15 |    75 |     5   (0)| 00:00:01 |
-------------------------------------------------------------------------------------

SQL> select count(*) from myemp1
  2  where sal = 100000
  3  or sal = 200000
  4  or sal = 300000;

  COUNT(*)
----------
        15

   : 00:00:00.01

---------------------------------------------
| Id  | Operation          | Name           |
---------------------------------------------
|   0 | SELECT STATEMENT   |                |
|   1 |  SORT AGGREGATE    |                |
|   2 |   CONCATENATION    |                |
|*  3 |    INDEX RANGE SCAN| IDX_MYEMP1_SAL |
|*  4 |    INDEX RANGE SCAN| IDX_MYEMP1_SAL |
|*  5 |    INDEX RANGE SCAN| IDX_MYEMP1_SAL |
---------------------------------------------



where절에 3개의 or 만으로는 inlist iterrator concatenation을 비교해 보기 어려워
이번에는 sal > 900000 이라는조건을 하나 더 줘보자. 그리고 통계정보도 보기 위해
set autotrace on 이라고 하자.

SQL>set autotrace on;

SQL> select count(*) from myemp1
  2  where sal = 100000
  3  or sal = 200000
  4  or sal = 300000
  5  or sal > 900000;

  COUNT(*)
----------
   5500010

   : 00:00:02.53


---------------------------------------------
| Id  | Operation          | Name           |
---------------------------------------------
|   0 | SELECT STATEMENT   |                |
|   1 |  SORT AGGREGATE    |                |
|   2 |   CONCATENATION    |                |
|*  3 |    INDEX RANGE SCAN| IDX_MYEMP1_SAL |
|*  4 |    INDEX RANGE SCAN| IDX_MYEMP1_SAL |
|*  5 |    INDEX RANGE SCAN| IDX_MYEMP1_SAL |
|*  6 |    INDEX RANGE SCAN| IDX_MYEMP1_SAL |

Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
      12973  consistent gets
      12963  physical reads
          0  redo size
        438  bytes sent via SQL*Net to client
        416  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

SQL> select /*+ index(myemp1 idx_myemp1_sal)  */ count(*) from myemp1
  2  where sal = 100000
  3  or sal = 200000
  4  or sal = 300000
  5  or sal > 900000;

  COUNT(*)
----------
   5500010

   : 00:00:01.50

--------------------------------------------------------------------------------------
| Id  | Operation           | Name           | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |                |     1 |     5 | 12745   (1)| 00:02:33 |
|   1 |  SORT AGGREGATE     |                |     1 |     5 |            |          |
|   2 |   CONCATENATION     |                |       |       |            |          |
|   3 |    INLIST ITERATOR  |                |       |       |            |          |
|*  4 |     INDEX RANGE SCAN| IDX_MYEMP1_SAL |    15 |    75 |     5   (0)| 00:00:01 |
|*  5 |    INDEX RANGE SCAN | IDX_MYEMP1_SAL |  5499K|    26M| 12740   (1)| 00:02:33 |
--------------------------------------------------------------------------------------

Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
      12972  consistent gets
          0  physical reads
          0  redo size
        438  bytes sent via SQL*Net to client
        416  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
1      rows processed

4 index range scan concatenation 했을 때는 physical read가 발생하며
inlist iterator의 경우 physical read 0이다 그리고 시간도 조금 단축되고
확인 바란다. 쿼리가 단문인 경우 별차이 없다고 느끼겠지만 장문의 반복적인 쿼리 에서는 많은 성능 차이가 날 것이다. 그리고 CBO인 경우 no_expend를 사용 안하더라도 인덱스가 있는 경우 알아서 inlist iterator 연산을 수행하도록 실행계획을 작성하니 별 걱정 안해도 될 것 같다