posted by 시드라엘 2015. 7. 10. 13:57

제목 : [ Java, Eclipse ] - 프로젝트에서 공통 플젝트 당겨쓰기



설명 : 

보통 규모가 큰 프로젝트에서는 공통 부분을 따로 빼서 나중에 jar파일로 꼽아준다.

하지만 공통부분이 조금씩 변화하는 프로젝트에서는 공통부분소스를 다운받아서 싱크 관리를 할 수도 있다.

뭐 메이븐써서 매번 배포할수도있겠지만... 지금 이야기 하고 싶은부분은 자주쓰면서 까먹는 부분




사용법 : 

1. 프로젝트 우클릭 -> Properties -> Java Build path -> Add class folder -> 해당프로젝트의 클래스 폴더 체크

2. 프로젝트 우클릭 -> Properties -> Deployment Assembly -> Add -> 자바빌드패스앤트리 ( 위에서 추가한것 ) -> 확인



결과 : 

이 작업이 선행되지 않으면 프로젝트에서 공통부분클래스를 찾지 못하므로 클래스 낫파운드 에러가 발생한다.

 


경험 : 

자주 안쓰다보면 까먹는다.


검색단어 :




posted by 시드라엘 2015. 7. 7. 10:08

제목 : Project Lombok



설명 : 

Project Lombok

URL : https://projectlombok.org/

가이드 : http://jnb.ociweb.com/jnb/jnbJan2010.html

내가 아는한 이놈이 겟터 셋터를 지정해줌 그외 몇가지 어노테이션을 사용할 수 있음


Lombok Annotations - @Getter @Setter @NonNull @ToString @EqualsAndHashCode @Data @Cleanup @Synchronized 

@SneakyThrows : 

@Getter 

@Setter 

@NonNull 

@ToString 

@EqualsAndHashCode 

@Data 

@Cleanup 

@Synchronized 

@SneakyThrows 




사용법 : 

1.

pom.xml 추가

pom.xml

<dependencies>

<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>0.9.2</version> </dependency> </dependencies> <repositories> <repository> <id>projectlombok.org</id> <url>http://projectlombok.org/mavenrepo</url> </repository> </repositories>


2.

이클립스에 lombok설치 ( 이게 라이브러리만 꼽는다고 되는게 아니라 롬복을 설치해야 한다. )

롬복 설치시 eclips.ini 파일에

-javaagent:lombok.jar -Xbootclasspath/a:lombok.jar

내용만 넣으면 된다고 하는데 난 안되더라. 그래서 설치를 해야하는데 설치하는방법은

CMD

java -jar C:\Java\repos\org\projectlombok\lombok\1.14.8\lombok.jar ( 롬복경로 )

하면 아래와 같은 창이 뜬다.


Specify location.. 버튼 -> 이클립스 설치된 경로의 eclipse.exe 를 선택

Install / Update   버튼

Quit Installer 버튼

이후 eclipse.ini 파일을 열어보면

-javaagent:lombok.jar -Xbootclasspath/a:lombok.jar

가 추가되있을것이다.



결과 : 

이클립스에서 나오던 겟터 세터 오류가 사라짐

 


경험 : 

이걸 사용한다고 딱히 좋다는 생각은 안든다. 왜냐면 난 VO를 안쓰는 편이거든.

거기다가 이클립스에 뭔가를 설치해야만 한다니.. 처음에 몰랐을때는 왜 게터세터에서 죄다 오류가 날까? 라고 생각함.

다수의 인원이 작업하는 플젝에선 인원이 나가고 들어오는경우가 많기때문에 이런걸 사용하면 개발세팅가이트 같은것을

잘 만들어 둬야 할것 같다.


검색단어 :

lombok







posted by 시드라엘 2014. 7. 1. 10:23

## 레이아웃 작업중 ## - http://jsfiddle.net/

참고 : http://html.nhncorp.com/uio_factory/ui_pattern/layout/5

<!-- top start-->

  <div class="header">

    header

  </div>

<!--// top start-->

<div class="wrap">

 <div class="container">

   <div class="left">

       left

   </div>

   <div class="center">

       body

   </div>

   <div class="right">

       right

   </div>

 </div>

</div>

<!--  하단 -->

  <div class="footer">

footer

  </div>



html { _filter:expression(document.execCommand("BackgroundImageCache", false, true))}

html, body{ height:100%; }

body .header{ height:50px; border:1px solid red; text-align:center; }

.wrap{ min-height:100%; margin:-50px 0 -100px 0;}

* html .wrap { *height:100% }

.wrap .container{ width:1250px; margin:0 auto; height:100%;}

.wrap .container .left{ border:1px solid blue; float:left; min-height:200px; width:200px; margin-top:50px; }

.wrap .container .center{ border:1px solid blue; float:left; min-height:200px; width:800px; margin-top:50px; }

.wrap .container .right{ border:1px solid blue; float:left; min-height:200px; width:200px; margin-top:50px; }

body .footer{ clear: both; height:100px; border:1px solid black; text-align:center; }



posted by 시드라엘 2013. 9. 9. 19:33

    //월요일을 중심으로한 주차 구하기

    //차일 변수
    var minusDay = 0;

    //주차를 계산하고픈 일
    var wkDtStr = "20130901";

    //계산하고픈달 시작일 1일
    var stDtStr = wkDtStr.substring(0,6) + "01";
    var stDtCal = new Date( stDtStr.substring(0,4) , stDtStr.substring(4,6) , stDtStr.substring(6,8) );
   
    //요일 구하기
    var weekCal = new Date( wkDtStr.substring(0,4) , ( wkDtStr.substring(4,6) - 1 ) , wkDtStr.substring(6,8) );

    //주차를 계산하고픈 일 달력 생성
    var wkDtCal = new Date( wkDtStr.substring(0,4) , wkDtStr.substring(4,6) , wkDtStr.substring(6,8) );

    //매달 시작일에 따른 빼줘야 하는 값
    var week = new Array( 1, 0, 5, 4, 3, 2, 1 );

    minusDay = wkDtCal.getDate() - stDtCal.getDate() - week[ weekCal.getDay() ] ;

    //만약 2일부터 1주차인데 1일을 입력했을경우 혹은 년도가 바뀔경우
    if( ( minusDay - week[ weekCal.getDay() ] ) < 0 ){

        wkDtCal.setDate( stDtCal.getDate() - 1 );
        stDtCal.setDate( stDtCal.getDate() - wkDtCal.getDate() );

        minusDay = wkDtCal.getDate() - stDtCal.getDate();

//        alert( "변경된 시작일 : " + stDtCal.getYear() + stDtCal.getMonth() + stDtCal.getDate() + "" );
//        alert( "변경된 마지막일 : " + wkDtCal.getYear() + wkDtCal.getMonth() + wkDtCal.getDate() + "" );
//        alert( "두 날짜 차일 : " + wkDtCal.getDate() - stDtCal.getDate() );
    }
   
    var weekNm = minusDay / 7 + 1;

    //연산
    alert( wkDtCal.getYear() + "년" + wkDtCal.getMonth() + "월" + parseInt(weekNm) + " 주차 " );

 

날짜를 집어넣으면 월요일 기준으로 주차를 계산하는 함수

쉽게 말해서 2013 년 10월 7일은  2013 년 10 월 1주차 로 계산됨 ( 2주차가 아님 )

무조건 월요일이 지나가야 1주차가 된다.

별거아닌거 짜면서 골 깨지는줄 알았음.. ㅋㅋ

posted by 시드라엘 2013. 7. 10. 11:18

조인의 종류


1.JOIN

둘 이상의 테이블 간의 논리적 관계를 기준으로 데이터를 검색하여 결과 집합을 만든다.

 

기본형식


SELECT 열 목록
   FROM 첫번째 테이블 join_type 두번째 테이블
       ON(join_condition)
* join_type : 수행될 조인 유형을 지정한다. (INNER, OUTER, CROSS, SELF)
* join_condition : 조인할 행의 각 쌍에 대해 선택할 조건을 정의한다. 일반적으로 키와 키를 지정

 

고려사항
1) 조인은 하나의 쿼리에서 여러 테이블이 참조되기 때문에 모든 열 참조는 명확해야 한다. (테이블이름.컬럼이름)
2) 조인조건은 FROM절이나 WHERE 절에 지정할 수 있으며 FROM 절에 지정하는 것이 좋다.
3) WHERE절과 HAVING 절에는 조인 조건에서 선택된 행을 자세히 필터링하는 검색 조건이 포함될 수 있다.

 


2. INNER JOIN
결합된 테이블에 조건의 내용이 공통으로 들어가 있는 값을 결과 집합으로 만들어준다. ON 다음에 들어가는 조건에 맞는 내용들만 보여주게 된다.


기본형식


SELECT 열 목록
   FROM 첫번째 테이블 [AS 별칭] INNER JOIN 두번째 테이블 [AS별칭]
       ON(join_condition)

 

SELECT 회원이름, 구매한도서, 작가, 구매시기
   FROM 회원정보 INNER JOIN 구매내역
 WHERE 회원이름 = '김군'

 

SELECT DISTINCT M.회원정보, M.회원이름, M.거주지역
   FROM 회원정보 AS M
   INNER JOIN 구매내역 AS B
       ON M.회원번호 = B.회원번호
 ORDER BY M.회원번호

 

SELECT M.회원이름, B.구매한도서, P.가격
  FROM 회원정보 AS M
  INNER JOIN 구매내역 AS B
      ON M.회원번호 = B.회원번호
  INNER JOIN 가격 AS P
      ON B.구매한도서 = P.구매한도서
 ORDER BY M.회원이름

 

 

2.2 OUTER JOIN
INNER JOIN 문을 포함하고 한쪽에만 내용이 있더라도 지정한 기준 테이블에 있는 모든 데이터를 가져오는 조인방식


기본형식

 

SELECT 열목록
   FROM 첫번째 테이블
   <LEFT | RIGHT | FULL> OUTER JOIN 두번째 테이블
       ON(join_condition)
   [WHERE 검색조건]

 

(1) LEFT OUTER JOIN
왼쪽 테이블이 기준이 되어서 그 테이블에 있는 데이터를 모두 가져온다. 기준으로 지정되지 않은 오른쪽 테이블에서 가져올 수 없는 열은 NULL로 표현된다.


SELECT M.회원이름, B.구매한도서, B.작가, B.구매시기
   FROM 회원정보 AS M
    LEFT OUTER JOIN 구매내역 AS B
      ON M.회원번호 = B.회원번호
 ORDER BY M.회원번호

 

(2) RIGHT OUTER JOIN
오른쪽 테이블이 기준이 되어서 그 테이블에 있는 데이터를 모두 가져온다. 기준으로 지정되지 않은 왼쪽 테이블에서 가져올 수 없는 열은 NULL로 표현된다.

SELECT B.구매한도서, B.작가, B.구매시기, M.회원이름
  FROM 회원정보 AS M
  RIGHT OUTER JOIN 구매내역 AS B
      ON M.회원번호 = B.회원번호
ORDER BY B.구매시기

 

(3) FULL OUTER JOIN
왼쪽과 오른쪽에 관계없이 조건이 일치하지 않아도 양쪽의 모든 내용을 포함해서 나타낸다.


SELECT M.회원이름, B.구매한 도서, B.작가, B.구매시기
   FROM 회원정보 AS M
    FULL OUTER JOIN 구매내역 AS B
 ORDER BY M.회원번호

 

 

2.3 CROSS JOIN
결과값이 한쪽 테이블의 모든행들과 다른쪽 테이블의 모든 행을 조인시킨다.
결과 집합은 두 테이블의 개수를 곱한 값만큼 생성되며, 조인되는 테이블에 공통되는 행이 없어도 되며 조건절인 ON 키워드가 사용되지 않는다.


SELECT M.회원이름, B.구매한도서, B.작가, B.구매시기
  FROM 회원정보 AS M
 CROSS JOIN 구매내역 AS B
 ORDER BY M.회원번호

 

 

2.4 SELF JOIN
하나의 테이블에 같은 데이터가 존재하는데 그 의미가 다르게 존재하는 경우. 즉, 같은 데이터이지만 다른 열에 있는 경우에는 두 테이블을 서로 SELF JOIN 문으로 확인가능


SELECT A.회원이름, A.주거지역, A.연락처, B.회원이름 AS 추천인, B.연락처
  FROM 회원정보 AS A
  INNER JOIN 회원정보 AS B
      ON A.추천한 회원 = B.회원번호
WHERE A.회원이름 = '김군'

 

posted by 시드라엘 2013. 7. 10. 11:17

Explain 정보보는법

1. 인덱스가 적절히 사용되고 있는지 검토
2. 나열된 순서는 MYSQL이 쿼리처리에 사용하는 순서대로 출력

 

 

EXPLAIN 의 각 행 설명
1. id : SELECT 번호, 쿼리내의 SELECT 의 구분번호, 실행순서

 

2. select_type : SELECT 의 타입
- SIMPLE: 단순 SELECT (UNION 이나 서브쿼리를 사용하지 않음)
- PRIMARY: 가장 외곽의 SELECT
- UNION: UNION 에서의 두번째 혹은 나중에 따라오는 SELECT
- DEPENDENT UNION: UNION 에서의 두번째 혹은 나중에 따라오는 SELECT, 외곽쿼리에 의존적
- UNION RESULT: UNION 의 결과물
- SUBQUERY: 서브쿼리의 첫번째 SELECT
- DEPENDENT SUBQUERY: 서브쿼리의 첫번째 SELECT, 외곽쿼리에 의존적
- DRIVED: SELECT 로 추출된 테이블 (FROM 절 내부의 서브쿼리)

 

3. table : table명

 

4. type : 조인타입, 우수한 순서대로… 뒤로갈수록 나쁜 조인형태
1) system : 테이블에 단 하나의 행만 존재(시스템 테이블). const join 의 특수한 경우 (거의 메모리에 상주)
2) const : 많아야 하나의 매치되는 행만 존재할 때, PRIMARY KEY 나 UNIQUE index 를 상수와 비교할 때, 각 컬럼값은 나머지 연산에서 상수로 간주, 처음 한번만 읽어들이면 되므로 매우 빠름
3) eq_ref : 조인수행을 위해 각 테이블에서 하나씩의 행만이 읽히는 경우, 조인연산에  PRIMARY KEY 나 UNIQUE index 인덱스가 사용되는 경우, 인덱스된 컬럼이 = 연산에 사용되는 경우
4) ref : 이전 테이블과의 조인에 사용될 매치되는 인덱스의 모든행이 이 테이블에서 읽혀질 때, leftmost prefix 키만을 사용하거나 사용된 키가 PRIMARY KEY 나 UNIQUE 가 아닐때
(즉 키값으로 단일행을 추출할수 없을때)
사용된 키가 적은수의 행과 매치되면 이것은 적절한 조인 타입.
ref 는 인덱스된 컬럼과 = 연산에서 사용됨
5) ref_or_null : ref 와 같지만 NULL 값을 포함하는 행에대한 검색이 수반될 때. 서브쿼리 처리에서 대개 사용됨
6) index_merge : 인덱스 병합 최적화가 적용되는 조인 타입. 이 경우, key 컬럼은 사용된 인덱스의 리스트를 나타내며 key_len 컬럼은 사용된 인덱스중 가장 긴 key 명을 나타냄
7) unique_subquery : 몇몇 IN 서브쿼리 처리에서 ref 타입대신 사용됨. unique_subquery 는 성능향상을 위해 서브쿼리를 단순 index 검색 함수로 대체함.
8) index_subquery : unique_subquery 와 마찬가지로 IN 서브쿼리를 대체. 단, 서브쿼리에서 non-unique 인덱스가 사용될때 동작 함
9) range : 인덱스를 사용하여 주어진 범위 내의 행들만 추출
key 컬럼: 사용된 인덱스 / key_len: 사용된 가장 긴 key 부분 / ref 컬럼: 이 타입의 조인에서 NULL
키 컬럼이 상수와 =, <>, >, >=, <, <=, IS NULL, <=>, BETWEEN 또는 IN 연산에 사용될때 적용됨
10) index : 인덱스가 스캔된다는걸 제외하면 ALL 과 같음. 일반적으로 인덱스 파일이 데이타파일보다 작기 때문에 ALL 보다는 빠름. MySQL 은 쿼리에서 단일 인덱스의 일부분인 컬럼을 사용할때 이 조인타입을 적용함
11) ALL
이전 테이블과의 조인을 위해 풀스캔. (조인에 쓰인) 첫번째 테이블이 고정이 아니라면 비효율적. 대부분의 경우에 아주 느린 성능
정리:
system - const - eq_ref - ref - ref_or_null - index_mergy - unique_subquery -  ndex_subquery - range - index - ALL

 

5. possible_keys : MySQL 이 해당 테이블의 검색에 사용할수 있는 인덱스들. possible_keys 에 나타난 인덱스들이 결과에 나타난 테이블 순서에서 실제 사용할 수 없을수도 있음

 

6. key :  MySQL 이 실제 사용한 key(index)

 

7. key_len : MySQL 이 사용한 인덱스의 길이, key 컬럼값이 NULL 이면 이값도 NULL
key_len 값으로 MySQL 이 실제 복수컬럼 키중 얼마나 많은 부분을 사용할 것인지 알 수 있음

 

8. ref : 행을 추출하는데 키와 함께 사용된 컬럼이나 상수값

 

9. rows : 쿼리 수행에서 MySQL 이 예상하는 검색해야할 행수

 

10. Extra : MySQL 이 쿼리를 해석한 추가적인 정보를 나타냄
1) Distinct: MySQL 이 매치되는 첫행을 찾는 즉시 검색을 중단한다는 의미
2) Not exists: MySQL 이 LEFT JOIN 을 수행함에 매치되는 한 행을 찾으면 더이상 매치되는 행을 검색x
3) range checked for each record (index map: #): MySQL 이 사용할 좋은 인덱스가 없음 의미
4) Using filesort: MySQL 이 정렬을 위해 추가적인 과정을 필요로 함
5) Using index: 컬럼정보가 실제 테이블이 아닌 인덱스트리에서 추출, 쿼리에서 단일 인덱스된 컬럼들만을 사용하는 경우
6) Using temporary: MySQL 이 결과의 재사용을 위해 임시테이블을 사용, 쿼리 내에 GROUP BY 와 ORDER BY 절이 각기 다른 컬럼을 사용할때 발생
7) Using where: WHERE 절이 다음 조인에 사용될 행이나 클라이언트에게 돌려질 행을 제한하는 경우 테이블의 모든 행을 검사할 의도가 아니면 ALL 이나 index 라면 쿼리사용이 잘못된 것임
Using sort_union(…) , Using union(…) , Using intersect(…)
Using index for group-by: Using index 와 접근방식이 같으며, 추가적인 디스크 접근 없이 GROUP BY 나 DICTINCT 쿼리에 사용된 모든 컬럼에 대한 인덱스를 찾았음을 의미

 

정리 : 쿼리를 가능한 한 빠르게 하려면, Extra 값의 Using filesort 나 Using temporary 에 주의해야 함
EXPLAIN 의 출력내용중 rows 컬럼값들을 곱해봄으로써 얼마나 효과적인 join 을 실행하고 있는지 알 수 있다

posted by 시드라엘 2013. 7. 10. 11:16

1. 메모리 영역(시스템글로벌 영역 SGA)
사용자가 실행한 SQL문에 의해 검색 또는 변경되는 테이블 데이터를 임시로 저장하는 메모 리 영역 시스템글로벌 영역(SYSTEM GLOBAL AREA)이라고 합니다. SGA 영역은 오라클 데이터베이스에서 가장 중요한 영역이며 데이터베이스의 크기를 결정하는 척도이고 전체 실행속도를 향상시키기 위한 튜닝의 대상이 되기도 합니다. 그리고, 데이터베이스에 접속하는 모든 사용자들이 공유하는 영역이며 기본적으로 오라클 데이터베이스 서버는 하나의 SGA 영역으로 구성되어 있습니다.

 

1) 공유 풀 영역(Shared Pool Area)
SQL*PLUS, 애플리케이션 프로그램 등에서 데이터베이스에 접속하면 하나의 사용자 프로세스와 하나의 서버 프로세스가 할당되고 사용자는 SQL문을 실행하게 됩니다. 그리고, 서버 프로세스는 SQL문의 문법(Syntax)을 확인하고 사용된 테이블이 데이터베이스 내에 존재하는지를 확인한 다음 SQL문의 실행 가능한 실행코드와 실행에 필요한 실행 계획(Explain Plan)을 수립하고 그 내용을 저장하는 곳이 공유 풀(Shared Pool) 영역입니다. 공유 풀 영역은 2가지 영역으로 구성되어 있는데 라이브러리 캐쉬(Library Cache) 영역에는 실행코드와 실행계획이 저장되고 자료사전 캐쉬(Data Dictionary Cache) 영역에는 사용자가 읽게 되는 자료사전 테이블과 뷰 정보가 저장됩니다.


2) 데이터 버퍼캐쉬 영역(Data Buffer Cache Area)
서버 프로세스는 사용자가 실행한 SQL문에 정의된 테이블이 존재하는 데이터 파일로부터 테이블을 읽어서 데이터베이스 버퍼 캐쉬(Buffer Cache) 영역에 저장합니다. 예를 들어, 윈도우 운영체제의 탐색기 화면에서 어떤 파일을 참조하기 위해 더블-클릭을 하면 파일의 데이터는 메모리의 버퍼영역에 로드되고 다시 편집 프로그램에 의해 화면에 출력됩니다. 이때 사용되는 메모리 버퍼 영역과 원리가 유사합니다.

3) 로그버퍼 영역(Log Buffer Area)
사용자가 실행한 DML문을 커밋(Commit)하면 화면에 '커밋이 성공적이다'라는 메시지를 보여줍니다.(또는 롤백을 실행하면 '롤백되었읍니다') 이때 커밋했던 모든 작업내용을 메모리의 로그 버퍼(Log Buffer) 영역에 저장하게 됩니다. 모든 작업내역을 리두로그 버퍼에 저장하는 이유는 갑작스런 시스템의 다운 또는 데이터베이스의 다운 시 처리하고 있던 모든 작업내용을 복구하기 위해서 입니다.
예를 들어, 윈도우 운영체제 시스템을 사용하다 시스템의 전원이 갑자기 꺼졌을 때 수행중인 작업이 존재했다면 다시 전원을 켰면 "복구모드"로 전환되어 복구작업을 수행합니다. 이러한 복구작업을 수행하기 위해서 운영체제는 항상 디스크의 일부공간에 작업내역을 백업해두었다가 복구 시 사용하게 되는데 이러한 원리와 같은 개념입니다.


4) 라지 풀 영역(Large Pool Area)
오라클 8.x 버전부터 백업과 복구작업을 실행할 때 복구관리자(Recovery Manager)라는 툴을 사용할 수 있고 또한, 사용자가 데이터베이스에 접속하는 방법 중에 공유서버(Shared Server) 프로세스라는 환경이 있는데 이러한 환경을 구성할 때 라지 풀 영역을 사용합니다.

 

 

2. 파일영역
데이터베이스의 마지막 구조인 파일영역에는 데이터베이스가 생성되면서 만들어졌던 자료사던 테이블과 뷰 그리고 사용자가 직접 생성한 테이블, 인덱스, 뷰, 시퀀스, 시노늄 등이 저장되어 있습니다. 또한, 데이터베이스의 모든 상태정보가 저장되어 있습니다. 파일영역을 "데이터베이스"라고 부르기도 합니다. 그럼, 보다 자세히 알아보도록 합시다.

 

1) 컨트롤 파일(Control Files)
데이터베이스를 시작(STARTUP)할 때 항상 참조되는 파일이 컨트롤 파일입니다. 왜냐하면, 컨트롤 파일은 데이터베이스에서 사용하게 될 모든 파일들의 절대경로와 파일크기 등의 정보를 저장하고 있기 때문에 파일들의 이상유무를 확인하기 위해서 참조하게 됩니다.(차후에 "백업과 복구"에서 자세히 소개됩니다.) 그리고 새로운 데이터 파일이 추가되면 해당 파일의 디렉토리 정보와 파일의 상태를 컨트롤 파일에 저장합니다.
오라클 데이터베이스가 시작되기 위해서는 최소한 하나의 컨트롤 파일이 존재해야 하는데 유니버셜 인스톨러에 의해 설치하면 3개의 컨트롤 파일이 기본적으로 생성됩니다. 이중에 하나는 원본이고 나머지는 복사 본 파일입니다. 컨트롤 파일은 오라클 데이터베이스가 존재하기 위해 꼭 필요한 파일이기 때문에 원본 컨트롤 파일에 문제가 발생하면(컨트롤 파일이 사용자에 의해 삭제되거나 컨트롤 파일이 존재하는 디스크가 깨지는 사태) 복사 본 컨트롤 파일로 대체해서 사용하기 위해서 입니다.


2) 파라메터 파일(Parameter File)
앞에서 배웠던 SGA 영역를 생각해 보십시오. SGA 영역은 시스템 메모리 영역으로부터 데이터베이스가 전용으로 사용하기 위해 할당받게 되는 영역입니다. 그렇다면, 시스템으로부터 얼마만큼의 메모리 크기를 할당받게 될까요 ? 그 의문의 해답을 가진 파일이 파라메터 파일입니다. 또한, 파라메터 파일은 컨트롤 파일의 경로, 데이터베이스의 환경설정 등 관련된 모든 정보를 포함하고 있습니다.
이 파일은 데이터베이스의 튜닝 시에도 사용되는 매우 중요한 파일 중의 하나입니다. 운용체제에 따라 약간의 차이는 있지만 기본적으로 데이터베이스를 설치하면 다음 그림과 같이 INIT<DB명>.ORA 또는 INIT.ORA 라는 파일 이름으로 존재합니다.

3) 로그버퍼 영역(Log Buffer Area)
사용자가 실행한 DML문을 커밋(Commit)하면 화면에 '커밋이 성공적이다'라는 메시지를 보여줍니다.(또는 롤백을 실행하면 '롤백되었읍니다') 이때 커밋했던 모든 작업내용을 메모리의 로그 버퍼(Log Buffer) 영역에 저장하게 됩니다. 모든 작업내역을 리두로그 버퍼에 저장하는 이유는 갑작스런 시스템의 다운 또는 데이터베이스의 다운 시 처리하고 있던 모든 작업내용을 복구하기 위해서 입니다.
예를 들어, 윈도우 운영체제 시스템을 사용하다 시스템의 전원이 갑자기 꺼졌을 때 수행중인 작업이 존재했다면 다시 전원을 켰면 "복구모드"로 전환되어 복구작업을 수행합니다. 이러한 복구작업을 수행하기 위해서 운영체제는 항상 디스크의 일부공간에 작업내역을 백업해두었다가 복구 시 사용하게 되는데 이러한 원리와 같은 개념입니다.

4) 라지 풀 영역(Large Pool Area)
오라클 8.x 버전부터 백업과 복구작업을 실행할 때 복구관리자(Recovery Manager)라는 툴을 사용할 수 있고 또한, 사용자가 데이터베이스에 접속하는 방법 중에 공유서버(Shared Server) 프로세스라는 환경이 있는데 이러한 환경을 구성할 때 라지 풀 영역을 사용합니다.

 

 

3. 백그라운드 프로세스
오라클 데이터베이스의 현재 상태를 모니터링하거나, 사용자가 실행한 SQL문의 작업을 처리해주는 프로세스를 백그라운드 프로세스라고 합니다. 백그라운드 프로세스에는 데이터베이스가 시작될 때 꼭 필요한 DBWR(Database Writer), LGWR(Log Writer), SMON(System Monitor), PMON(Process Monitor), CKPT(CheckPoint)가 있습니다. 만약, 5개의 백그라운드 프로세스 중 하나라도 존재하지 않는다면 데이터베이스는 더 이상 사용할 수 없습니다. 그리고, 이 5개의 프로세스를 필수 백그라운드 프로세스라고 합니다.

 

1. DBWR 프로세스
데이터베이스 기록기(DBWR)는 사용자가 실행한 SQL문에 의해 데이터의 변경내역(입력, 수정, 삭제)을 테이블에 저장하는 작업을 수행합니다. 예를 들어, 사용자가 UPDATE문을 실행하고 커밋(Commit)문을 실행할 때 테이블에 데이터를 저장하는 작업을 데이터베이스 기록기 프로세스가 처리합니다. 데이터베이스 기록기(DBWR)와 로그 기록기(LGWR)는 데이터베이스를 시작하면 자동으로 생성되고 종료하면 없어지는 백그라운드 프로세스입니다.

2. LGWR 프로세스
사용자가 실행한 SQL문을 커밋(Commit)하면 화면에 '커밋이 성공적이다'라는 메시지를 보여줍니다. 이때 커밋했던 모든 작업내용을 리두로그 파일에 백업 하게되는데 이러한 작업을 로그 기록기(LGWR)가 처리해 줍니다. 모든 작업내역을 리두로그 파일에 저장하는 이유는 갑작스런 시스템의 다운 또는 데이터베이스의 다운 시 처리하고 있던 모든 작업내용을 다시 복구하기 위해서 입니다.

3. PMON 프로세스
사용자들이 데이터베이스에 접속하면 한번의 접속 요구마다 사용자 프로세스가 하나씩 생성됩니다. 프로세스 모니터(PMON)는 이러한 사용자 프로세스들의 상태를 감시합니다. 만약 어떤 사용자 프로세스에 오류가 발생하거나(예를 들어, SQL*PLUS에서 SQL문을 실행하는 중에 윈도우를 닫게 된다면) 또는 사용자 프로세스가 비정상적으로 종료된 경우 모든 작업을 자동적으로 롤백(Rollback) 시켜줍니다.

4. SMON 프로세스
시스템 모니터(SMON)는 백그라운드 프로세스와 데이터베이스 메모리 영역의 상태를 감시하며 데이터베이스가 다운된 후 다시 시작될 때 자동적인 복구작업을 수행해 줍니다.

5. CKPT 프로세스
체크포인트(CKPT)는 LGWR 프로세스에 의해 활동하며 사용자가 COMMIT문을 실행할 때마다 오라클 서버가 관리하는 시스템 변경번호(SYSTEM CHANGE NUMBER) 및 데이터베이스의 상태정보를 컨트롤 파일과 데이터 파일에 저장하는 작업을 하게됩니다. 또한, CKPT 프로세스가 발생하면 연속적으로 DBWR 프로세스가 작업을 수행하게 됩니다.

6. 기타 백그라운드 프로세스
5개의 필수 백그라운드 프로세스뿐만 아니라 경우에 따라서 사용할 수 있는 ARCH(Arch Iver), RECO(Recoverer), LCKn(Lock) 등의 기타 백그라운드 프로세스도 있습니다. ARCH 프로세스는 데이터베이스를 복구모드로 운영할 때 사용하며 RECO 프로세스는 분산 DB환경에서 서로 공유되는 객체 간의 동기화를 설정할 때 사용됩니다. 또한, LCKn프로세스는 병렬서버환경(Oralce Parallel Server)에서 테이블의 잠금과 관련된 백그라운드 프로세스입니다.

 

posted by 시드라엘 2013. 7. 10. 11:15

클러스터 팩터

1) 클러스터 팩터란

-> 인덱스 스캔을 통해 액세스 된 row수와 액세스한 테이블 블록 수와의 관계로써 액세스하고자 하는 데이터들이 얼마나 모여있는가를 뜻한다.

 

2) 클러스터 팩터의 법칙

클러스터 팩터값 = (인덱스 스캔을 통해 액세스 된 row ) / (액세스 한 테이블 블록 수)

 

|------------|------------------------------------------------------------|

0           1                                     인덱스 스캔을 통해 액세스된 row

 

) 클러스터 팩터값이 인덱스 스캔을 통해 엑세스 된 row수에 근접할 경우

(액세스한 테이블 블록수가 1에 가까운 경우)  -> 양호 또는 최적화 되어있다.

) 클러스터 팩터값이 1에 근접한 경우

(인덱스 스캔을 통해 액세스 된 row 수와 세스 한 테이블 블록 수가 거의 같은 경우) -> 불량

) 클러스터 팩터의 값이 0에 근접한 경우

(인덱스 스캔을 통해 액세스 된 row수가 0에 가까운 경우) -> 해당 테이블에 row 체이닝 현상이 발생하여 하나의 row가 두개의 블럭에 저장된 것으로 반드시 테이블 재구성이 필요하다.

(row 체이닝 : 하나의 row 길이가 너무 커서 다른 블럭에 두고 연결)

 

3) 클러스터 팩터 최적화 방법

) 주기적인 테이블 재구성

) cluster Table(DML시 성능 저하로 사용잘 안함) : 같은 레코드가 한 블록에 모이게 저장하는 구조

) index-Organized Table(IOT) : 액세스가 발생하지 않도록 인덱스 구조로 생성된 테이블

 

posted by 시드라엘 2013. 7. 10. 11:14

* B*TREE Index

 - Search, Delete, Insert 등에 효율적

 - 어느 Row등 동일 Index를 Scan하여 찾는다고 하면 같은 개수의 Block을 찾아올 수 있는 구조

 - Double Linked List를 이용하여 Range Scan 시에도 유리

 - Delete가 많거나 또는 Index Key가 순차적으로 증가하여 Insert되는 Table은

   주기적인 Index Rebuild를 통한 Index Balance 유지가 필요

 

## 장점

 1. Search 시 모든 Index Entry에 대해 Balance를 맞춤

 2. Range Scan 시 Double Linked List를 사용하기 때문에 유리

 3. OLTP로 적은 Row Access 유리

 

## 단점

 1. Cardinality가 낮은 컬럼에 대해서는 불리

 2. OR 연산자에 대해 Table Full Scan 위험 (오라클 옵티마이저 경향) => IN 연산자로 변경하여 사용

 

* 비트맵 Index

 - Yes or No인 값에 대하여 하나의 인덱스 엔트리에 여러개의 행정보가 들어감

 - OLTP 부적합

 - ad-hoc 으로 많은 열을 참고하는 질의나 COUNT 같은 집계를 하는 질의가 많은 경우 유용

 

* 함수 기반(function-based) Index - 8.1.5 이상

 - 대소문자 구별이 없는 탐색이나 정렬, 또는 복잡한 수식에 대한 탐색 등을 사용시 유용

 - 기존 애플리케이션의 로직이나 질의를 전혀 바꾸지 않고도 수행 속도를 개선

 - Cost based optimizer를 사용할때만 사용. rule based optimizer에서는 사용되지 않음.

 - Data Insert시 느려짐

 - TO_DATE 불가

 

* 애플리케이션 도메인 Index

 - 데이터베이스에는 아직 없는 새로운 인덱스 유형을 만들 수 있도록 해줌

 - ex) 인터미디어(interMedia) 텍스트 인덱스

 

Cluster Factor (인덱스의 값을 기반으로 테이블의 행들이 순서대로 되어 있는 정도)

1. 데이터 조회시 인덱스를 통해 데이터 RowId 조회후 해당 Table Block을 조회하게 되는데

  이 둘의 관계를 Cluster Factory라고 함. 조회할 데이터들이 같은 공간에 잘 정리되었는지 여부.

 ex) 1인 경우 = 100 Row 추출시 100 Block 조회 (Cluster Factor가 불량)

       0에 근접한 경우 (Table에 Row Chaining 현상 - 하나의 Row가 2개의 Block에 저장)

 

값이 블록의 개수에 가까우면 테이블이 매우 잘 정렬되어 있다는 의미

값이 행의 개수에 가까우면 테이블이 매우 임의적인 순서로 있다는 의미

 

2. 최적화 방법

 - 주기적인 Table 재구성(Order By 이용)

 - Partition Table

 - Cluster Table (DML 성능 저하로 거의 미사용)

 - Index-Organized Table(IOT)

 

3. 주기적인 Table 재구성 사례

 1. 임시 테이블로 정렬하여 Loading (기존 테이블과 TableSpace 동일해야 함)

 2. 서비스 정지

 3. 기존 테이블과 임시 테이블을 Switch

(ALTER TABLE_NAME EXCHANGE PARTITION 200403

  WITH TABLE 200403_TEMP INCLUDING INDEXES; )

 

 

posted by 시드라엘 2013. 7. 10. 11:14

1. 추출할 행을 분석

2. WHERE 절에 정의된 컬럼에 대한 인덱스 생성 여부확인

3. 인덱스 종류 분석후 SELECT LIST 컬럼 절을 결정 (SELECT * => 불필요한 스캔이 발생해 성능저하)

4. JOIN 컬럼과 인덱스 구조를 분석하여 구동테이블을 결정 (ROW가 적은것을 선택)

5. 구동 TABLE과 내부 TABLE 간의 관계를 고려