'02.Oracle/DataBase'에 해당되는 글 232건

  1. 2010.12.10 oracle 세로 출력값을 가로로 출력하기
  2. 2010.11.30 ms-sql 백업과 복원 (펌)
  3. 2010.10.29 oracle_sql강좌.pdf
  4. 2010.08.20 oracle null sum
  5. 2010.08.16 weblogic.jdbc.extensions.ConnectionDeadSQLException
  6. 2010.06.24 Oracle의 문자열비교
  7. 2010.06.16 오라클 튜닝 관련
  8. 2010.06.16 [DB]여러개의 로우를 하나의 컬럼으로 변환
  9. 2010.04.19 [오라클] like 연산에서 %, _ 문자로 검색하기 1
  10. 2010.04.05 oracle commit 후 복구
  11. 2009.12.09 오라클 데이타딕셔너리
  12. 2009.11.27 SQL문 튜닝 개요
  13. 2009.11.25 오라클 드라이버 버전 및 크기
  14. 2009.11.05 [[oracle_tablespace_copy
  15. 2009.11.05 imp시 tables 틀릴경우 ,10G DATAPUMP: REMAP TABLESPACE 기능
  16. 2009.10.20 [oracle]ORA-12541 TNS:리스너가 아닙니다
  17. 2009.10.20 [oracle]lock걸린 table 및 sql찾기
  18. 2009.10.20 오라클 테이블 락 ( Table lock )
  19. 2009.10.19 토드에서 save as를 통한 엑셀 저장시 한글깨짐 현상발생시 아래와 같은방법을 사용한다
  20. 2009.10.19 토드(toad)에서 한글이 깨져보일때
  21. 2009.09.24 ORA-02069: global_names parameter must be set to TRUE for this operation
  22. 2009.09.03 오라클에서의 데이터 암호화 기능
  23. 2009.08.12 오라클 테이블별 현황보기
  24. 2009.08.12 오라클 실행계획(explan table) 보기(분석)
  25. 2009.08.12 오라클 내장함수
  26. 2009.08.12 오라클 한글 자음 검색 2
  27. 2009.08.10 오라클 clob 예제
  28. 2009.07.29 Oracle SQL Developer 전체기능
  29. 2009.07.29 oracle 공백 제거
  30. 2009.07.14 데브피아 컬럼] DB 튜닝 이야기 - (2회) INDEX 과연 달면 빠른가?
02.Oracle/DataBase2010. 12. 10. 13:30
반응형

SELECT 컬럼,
        LTRIM(sys_connect_by_path(컬럼,','),',') AS 컬럼명
FROM  (
        SELECT 컬럼,
        menurole_id,
        row_number() OVER (partition by 그룹컬럼 order by 정렬할컬럼) rn,
        COUNT (*) OVER (partition by 그룹컬럼 ) cnt
        FROM 테이블명
)
WHERE level = cnt
start with rn = 1
connect by prior 그룹컬럼 = 그룹컬럼 and prior rn = rn-1


====================================================================

 세로로 출력되는 값들이 가로로 출력되는걸 확인할수 있다.


컬럼1  
컬럼2

1                  나

2                  너

1                  우리

1                  개똥이


컬럼1       컬럼2

1                 나,우리,개똥이

2                 너


출처 : http://kinjsp.pe.kr/board/board_view.kin?boardId=721.0&boardTypeCode=1072&fastFlag=true&numberPerPage=10&pageNumber=0

출처 : http://kinjsp.pe.kr/board/board_view.kin?boardId=721.0&boardTypeCode=1072&fastFlag=true&numberPerPage=10&pageNumber=0

Posted by 1010
02.Oracle/DataBase2010. 11. 30. 13:44
반응형

출처:http://www.sqlworld.pe.kr/index.asp

저작권 문제시 즉시 삭제가능~!!!

===========================================================================

백업장치

===========================================================================

1. 백업 장치? 돈주고 사나요?

백업 장치를 만든다는 것은 어떤 하드웨어적인 장치를 준비하는 것을 이야기 하는 것이 아닙니다. 여기서 이야기 하는 백업 장치는 물리적인 파일 이름이 길고 복잡하기 때문에 이를 쉽게 사용하기 위해서 하나의 별칭(Alias)를 만들어 두는 것을 이야기 합니다. 기억하실지 모르겠지만 데이터베이스를 만들 때 물리적인 파일의 경로와 이름을 지정하는 것 이외에 논리적인 데이터베이스 파일명을 지정하게 됩니다. (기억이 안난다면 데이터베이스 관련 강좌를 한번 보고 오시기 바랍니다).

2. 백업 장치의 필요성

예를 들어 "C:\Program FIles\Microsoft SQL Server\MSSQL\Backup\sqlworld.bak" 이라는 이름의 물리적인 파일로 백업을 받는다고 했을 경우 너무나 긴 경로명 때문에 왠지 짜증이 납니다. 이를 해결해 주는 것이 바로 백업장치명, 즉 논리적인 파일명이 됩니다.

나중에 보겠지만 다음과 같은 백업을 받은 T-SQL 문이 있가도 가정하겠습니다.

BACKUP DATABASE sqlworld
TO DISK = 'D:\Program Files\Microsoft SQL Server\MSSQL\Backup\sqlworld.bak'

위에서 빨간색 부분의 파일 경로는 너무나 길고 짜증납니다. 하지만 앞으로 배우게 될 방법으로 백업장치인 sqlworld를 만들어 놓게 되면 위 백업 문장은 다음과 같이 바뀌게 됩니다.

BACKUP DATABASE sqlworld TOsqlworld

매우 간단한 백업 문장이 되었습니다. 이것이 백업 장치의 위력(?) 입니다.

3. 백업 장치 만들기

백업 장치를 만드는 방법은 두가지가 있습니다. 추측하시다 시피 EM(Enterprise Manager)를 이용한 방법이 있고 T-SQL문을 이용하는 방법이 있습니다. 이 두가지 방법에 대하여 자세히 살펴보도록 하겠습니다.

[참고]

대부분의 작업들이 EM을 이용해서도 가능하고 T-SQL문을 이용해서도 가능합니다. 이중에 어느것을 사용하는게 좋은지 묻는 경우가 있습니다. EM의 경우는 대화 화면을 보면서 작업을 하기 때문에 더 쉽게 작업을 할 수 있습니다. 하지만 했던 작업을 다시 하려고 하면 처음부터 다시 해주어야 하는 경우가 많습니다. 하지만 T-SQL 문을 작업을 하고 저장해 둔 후 다음에 다시 이용 할 수 있는 장점이 있습니다. 그리고 예기치 않게 EM을 사용하지 못하게 되는 경우 T-SQL 문에 익숙한 관리자는 작업을 별 문제 없이 해 낼 수 있지만 EM에만 의존했던 관리자는 아무 작업도 못하고 발만 동동 구르게 됩니다. T-SQL 문을 통한 관리 방법을 꼭 익히시기 바랍니다.

1) EM을 이용한 백업 장치 만들기

① 아래 [그림 1]과 같이 백업 장치를 만드는 부분을 EM에서 볼 수 있습니다.


[그림 1]

② 아래 [그림 2] 처럼 "백업" 위에서 마우스 오른쪽 버튼을 눌러 표시되는 단축메뉴에서 "새 백업 장치(N)"를 선택하면 [그림 3] 과 같은 대화창이 뜹니다.


[그림 2]

③ 아래 [그림 3] 처럼 "이름" 부분에 원하는 장치명을 입력합니다. 되도록 의미가 있는 이름으로 하시는게 좋습니다. 그리고 "파일 이름" 부분에는 실제로 물리적인 경로가 어떻게 되는지 정해 주시면 됩니다. 결로을 정해주시면 기본적으로 입력한 "이름" + ".bak" 이 물리적인 파일 이름으로 지정됩니다.


[그림 3]

④ 아래 [그림 4] 는 sqlworld 라는 이름으로 백업장치가 만들어진 결과를 보여 줍니다.


[그림 4]

[참고]

위와 같은 과정으로 백업장치를 만들었다고 해서 지정했던 물리적인 경로의 파일(위의 경우는 E:\Data\sqlworld.bak")이 즉시 생기지 않습니다. 실제로 물리적인 파일이 생기는 시점은 첫번째 백업이 이루어지는 때입니다.

2) T-SQL 문을 이용한 백업 장치 만들기

T-SQL 문을 이용한 백업장치 만들기는 아주 간단합니다. 위에서 EM을 통해서 했던 작업을 T-SQL 로 한다면 다음과 같습니다.

USE master
GO

EXEC sp_addumpdevice 'disk', 'SQLWORLD', 'E:\Data\sqlworld.bak'

o disk : 하드 디스크로 덤프 받음을 의미합니다.(이외에 pipe, tape 등이 있습니다)
o SQLWORLD : 논리적인 백업 장치 명입니다.
o E:\Data\sqlworld.bak : 물리적인 파일의 경로와 파일명입니다.

sp_addumpdevice 저장프로시져에 대한 자세한 설명을 원하시면 온라인 설명서(Books Online)을 참조하여 주시기 바랍니다.

이제 우리가 만든 백업장치에 백업을 받으면 됩니다. 이어지는 전체 백업(Full Backup) 관련 강좌에서는 백업장치를 이용하여 백업을 받는 방법과 백업장치를 이용하지 않고 백업을 받는 방법에 대하여 살펴보도록 하겠습니다.

========================================================================================

Full Backup

========================================================================================

1. 전체 백업(Full Backup)의 특징

여러가지 백업 방법을 설명하면서 전체 백업에 대해서도 간단히 언급을 했었습니다. 전체 백업은 말 그대로 데이터베이스 전체를 백업 받는 것을 의미합니다. 데이터베이스 사이즈가 작은 경우라면 전체 백업을 받는데 별 무리가 없겠지만 데이터베이스 사이즈가 큰 경우라면 전체 백업은 그리 좋은 방법이 아닙니다. 전체 백업을 사용할 수 있는 경우를 생각해 본다면 다음과 같지 않을까 생각합니다.

o 개발용 데이터베이스를 현재 상태로 보관하고 싶은 경우 전체 백업
o 데이터베이스를 다른 서버로 옮기고 싶은 경우 전체 백업해서 다른 서버에 전체 복원
o 데이터베이스에 어쩌다 가끔 변경이 생기는 경우 이를 보관하기 위해 전체 백업
o 현재의 Master 데이터 베이스 보관을 위해 전체 백업

몇가지 생각나는 경우를 적어 보았는데 이게 정답이 아닐 수 도 있습니다.

2. 전체 백업 수행

그럼 전체백업을 받는 과정을 보도록 하겠습니다. 여기서는 다음과 같이 3가지 경우를 살펴 보도록 하겠습니다.

o EM에서 백업 장치를 이용한 전체 백업
o EM에서 물리적인 파일을 이용한 전체 백업
o T-SQL 문을 이용한 전체 백업

1) EM에서 백업 장치를 이용한 전체 백업

바로 이전의 강좌에서 만든 SQLWORLD라는 이름의 백업장치가 있었습니다. 이 백업 장치에 sqlworld 데이터베이스를 전체 백업받는 과정을 보도록 하겠습니다. 강좌를 보시는 분들은 연습용 데이터베이스가 없으면 pubs 데이터베이스를 백업받아 보시기 바랍니다.

① sqlworld데이터베이스 위에서 마우스 오른쪽 버튼을 눌러 [모든작업] - [데이터베이스 백업] 을 선택하시면 아래 [그림 1] 과 같은 대화 창이 표시됩니다.


[그림 1]

② "이름(N)" 부분과 "설명(R)" 부분에는 참고할 만한 내용을 입력합니다. 위 [그림 1] 에서 처럼 빨간색 라인 부분을 보면 백업 방법이 "데이터베이스-전체(D)" 로 되어 있습니다. 즉 전체 백업을 받음을 의미합니다. 백업 대상 부분의 현재 내용이 있으면 [제거(M)] 버튼을 눌러 제거 하시고 [추가(A)] 버튼을 눌러 아래 [그림 2] 처럼 장치 선택화면이 나오도록 합니다. 그리고 "백업장치(B)" 부분에 이미 만들어져 있는 SQLWORLD 라는 백업장치를 선택하고 [확인] 버튼을 누릅니다.


[그림 2]

③ 아래 [그림 3]을 보시면 "덮어쓰기" 부분이 보입니다. 이 부분은 만일에 백업 장치에 기존에 백업 받은 내용이 있으면 여기에 추가 할 것인지(미디어에 추가) 아니면 기존의 내용을 지우고 쓸 것인지(기존 미디어 덮어쓰기)를 선택하는 것입니다. 처음 백업 받는 것이므로 현재는 무엇을 선택하든 아무 의미가 없습니다. "예약" 부분은 스케쥴을 설정하여 백업받는 것인데 다음에 자세히 다루도록 하겠습니다.


[그림 3]

④ 위 화면에서 [확인] 버튼을 누르면 백업 진행 상황이 보이면서 실제 백업이 이루어 집니다. 백업이 완료 되었으면 백업 장치를 만들 때 지정했던 물리적인 폴더에 실제 백업 파일이 생성되었나 확인해 보시기 바랍니다.

⑤ SQLWORLD 백업 장치의 [등록정보]를 열어 [내용보기] 버튼을 누르면 아래 [그림 4]와 같이 백업 받은 히스토리가 표시됩니다.


[그림 4]

[실습 1] 다음을 실습해 보시기 바랍니다.

위 과정을 이용하여 같은 데이터베이스(예제의 경우 sqlworld)를 동일한 백업장치(예제의 경우 SQLWORLD)에 여러번 백업을 받아 보시기 바랍니다. 백업을 받는 과정에서 [그림 3]의 "덮어쓰기" 부분을 바꾸어 가면서 백업을 받아 보시기 바랍니다. 그리고 [그림 4]와 같이 백업 히스토리를 확인해 보시기 바랍니다. "덮어쓰기"를 어떻게 선택하냐에 따라 변화된 히스토리를 볼 수 있을 것입니다.

2) EM에서 물리적인 파일을 이용한 전체 백업

위 백업 방법과 대부분 동일 합니다. 단 [그림 2]에서 "백업 장치" 대신 "파일 이름" 부분에 원하는 물리적인 파일의 경로와 파일의 이름을 설정해 주면 됩니다. 자세한 설명은 생략하도록 하겠습니다. 직접 해보시기 바랍니다.

3) T-SQL 문을 이용한 전체 백업

BACKUP DATABASE 문을 이용해서 백업 장치 또는 물리적인 파일에 직접 백업을 받을 수 있습니다. 몇가지 다양한 예를 들어 보도록 하겠습니다.

[예제 1]

USE Master
GO

BACKUP DATABASE sqlworld TO SQLWORLD WITH INIT

o sqlworld 데이터베이스를 SQLWORLD 라는 백업 장치로 백업을 받습니다.
o WITH INIT 옵션은 기존의 백업 내용이 있으면 덮어 쓰라는 설정입니다.

[예제 2]

USE Master
GO

BACKUP DATABASE sqlworld TO SQLWORLD WITH NOINIT

o sqlworld 데이터베이스를 SQLWORLD 라는 백업 장치로 백업을 받습니다.
o WITH NOINIT 옵션은 기존의 백업 내용을 보존하고 거기에 추가하여 백업 받으라는 설정입니다. 결국 백업 파일의 사이즈는 증가하게 됩니다. INIT 이나 NOINIT을 설정하지 않으면 NOINIT이 기본으로 적용됩니다.

[예제 3]

USE Master
GO

BACKUP DATABASE sqlworld TO DISK = 'E:\Data\sqlworld.bak' WITH NOINIT

o sqlworld 데이터베이스를 E:\Data\sqlworld.bak 라는 물리적인 파일로 백업을 받습니다.
o 앞의 [예제 1]과 [예제 2]와는 다르게 TO 대신 TO DISK 로 바뀌었음을 숙지하시기 바랍니다.

BACKUP DATABASE 에 대한 자세한 설명은 온라인 설명서(Books Online)을 통해 필히 확인하시기 바랍니다. 다양한 옵션들이 제공됩니다. 물론 이들이 자주 사용되는 옵션은 아니지만 이런것도 있구나..라고 확인은 해보시기 바랍니다. 다음 강좌에서는 전체 백업 받은 것을 복구하는 과정을 살펴보도록 하겠습니다.

========================================================================================

Full Backup Restore

========================================================================================

1. 데이터베이스 복원(Restore)이란?

데이터베이스 복원이란 백업받은 것을 사용가능한 데이터베이스로 원위치 시키는 작업을 이야기 합니다. 데이터베이스를 운영하는 동안에 한번도 복원을 할 일이 없다면 좋겠지만 분명 언젠가는 복원을 해야하는 경우가 발생하므로 그 방법을 미리 알고 있어야 합니다. 특히 백업받은 내용이 정확한지 혹은 백업받은 내용이 물리적으로 손상되지는 않았는지 모의 복원을 통해 확인해보는 것도 중요하다고 생각합니다. 복원 방법을 전혀 모르는 상태에서 데이터베이스에 심각한 문제가 생겼을 때 백업 파일을 가지고 발만 동동 구르는 일이 없어야 하겠습니다. 데이터베이스 복원을 하게 되는 경우를 찾아본다면 다음과 같지 않을까 생각합니다.

o 데이터베이스에 심각한 문제가 발생하여 복원을 통한 복구가 불가피한 경우
o 다른 서버에서 백업받은 내용을 새로운 서버에 복원해야 하는 경우
o 백업받은 내용을 가지고 실제 데이터베이스와 비슷한 테스트용 데이터베이스를 만들고자 하는 경우

2. 전체 백업을 이용한 데이터베이스 복원 작업

바로 이전의 강좌에서 우리는 sqlworld 데이터베이스를 전체 백업 받았습니다. 이 전체 백업을 이용해서 데이터베이스 복원하는 방법을 살펴보도록 하겠습니다. 나중에 살펴보도록 하겠지만 차등 백업이나 트랜잭션 백업을 받은 경우의 데이터베이스 복원은 더 복잡합니다.

이 강좌에서는 다음의 두가지 방법을 이용한 데이터베이스 복원 방법을 살펴보도록 하겠습니다.

o 데이터베이스가 연결되어 있는 경우 EM에서 데이터베이스 복원
o 데이터베이스가 연결되어 있지 않는 경우 EM에서 데이터베이스 복원
o T-SQL 문을 이용한 데이터베이스 복원

1) 데이터베이스가 연결되어 있는 경우 EM에서 데이터베이스 복원

① 아래 [그림 1]와 같이 sqlworld 데이터베이스를 선택한 상태에서 [도구] 메뉴에서 "데이터베이스 복원(R)" 을 선택하시면 데이터베이스 복원을 위한 대화창이 표시됩니다.


[그림 1]

② [그림 2]와 같은 대화창이 표시되면 [도움말] 버튼을 눌러 각 항목에 대한 의미를 살펴보시기 바랍니다. 빨간색 부분에서 복원할 백업내역을 선택하고 [확인] 버튼을 누르면 복원이 진행됩니다.


[그림 2]

2) 데이터베이스가 연결되어 있지 않는 경우 EM에서 데이터베이스 복원

① 아래 [그림 3]을 보시면 sqlworld 데이터베이스가 제거된 상태입니다. 이 상태에서 복구를 하는 방법은 약간 다릅니다. 위의 방법과 동일하게 [도구] 메뉴에서 "데이터베이스 복원(R)" 을 선택하시면 데이터베이스 복원을 위한 대화창이 표시되나 [그림 2]와 같이 sqlworld 데이터베이스에 대한 백업 내역이 표시되지 않습니다.


[그림 3]

② [그림 4]와 같이 대화창이 표시되면 "데이터베이스로 복원" 부분에 sqlworld라고 입력하고 [장치내용]을 선택하고 [장치선택] 버튼을 누르면 [그림 5]와 같이 백업 장치나 백업 파일을 선택하는 대화창이 표시됩니다.


[그림 4]

③ [그림 5]와 같이 대화창이 표시되면 [추가] 버튼을 눌러 표시되는 "복원할 위치 선택" 창에서 SQLWORLD 백업장치를 선택하면 됩니다. 백업 장치가 아니고 물리적인 파일인 경우는 "파일이름" 부분을 선택하고 물리적인 파일을 지정하시면 됩니다.


[그림 5]

④ [그림 6]은 백업 장치 선택이 끝난 화면입니다. 이 화면에서 [내용보기] 버튼을 누르면 백업 내역이 표시되며 이 중에서 복원하고자 하는 시점의 백업 내역을 선택하시면 됩니다.


[그림 6]

3) T-SQL 문을 이용한 데이터베이스 복원

RESTORE DATABASE 문을 이용해서 백업 장치 또는 물리적인 파일로부터 데이터베이스를 복원 할 수 있습니다.

[예제 1]

USE Master
GO

RESTORE DATABASE sqlworld FROM SQLWORLD

o sqlworld 데이터베이스를 SQLWORLD 라는 백업 장치로부터 복원합니다.

[예제 2]

USE Master
GO

RESTORE DATABASE sqlworld FROM DISK = 'E:\Data\sqlworld.bak'

o sqlworld 데이터베이스를 E:\Data\sqlworld.bak 라는 물리적인 파일에서 직접 복원 합니다.

RESTORE DATABASE 에 대한 자세한 설명은 온라인 설명서(Books Online)을 통해 필히 확인하시기 바랍니다. 다양한 옵션들이 제공됩니다. 물론 이들이 자주 사용되는 옵션은 아니지만 이런것도 있구나..라고 확인은 해보시기 바랍니다. 다음 강좌에서는 차등 백업과 트랜잭션 백업에 대하여 살펴보도록 하겠습니다.

========================================================================================

Differential Backup/Restore

========================================================================================

1. 차등 백업(Differential Backup)의 특징

데이터베이스 차등 백업이란 전체 백업(Full Backup) 이후에 변경된 데이터만 백업받는 방법입니다. 예를 들어서 현재 100GB 정도의 데이터베이스가 있고 어제 저녁에 전체 백업을 받았다고 가정 하겠습니다. 오늘 하루 동안 입력된 데이터가 1,000건 정도 있다고 했을 때 가장 효과적인 백업(트랜잭션 백업을 제외하고)은 오늘 변경된 1,000 건의 데이터에 대한 백업만 받는 것입니다. 이후에 문제가 발생하게 되면 어제 받은 전체 백업을 복원하고 오늘 추가로 백업 받은 변경분 백업만 이어서 복원하게 되면 전체 데이터가 복원됩니다.

그래서 차 등백업이 효과적인 경우는 전체 데이터베이스 사이즈가 너무 커서 전체 백업을 받기에 너무 부담이 되는 경우입니다. 단지 변경 내용만 백업 받게 되면 짧은 시간에 백업을 받을 수 있어 효과적입니다. 중요한 것은 차등 백업만 있으면 아무 의미가 없다는 것입니다. 전체 백업 받은 것이 있어야 차등 백업이 의미가 있습니다. 다시 말하면 문제가 발생하여 데이터베이스 복원을 해야 하는데 차등 백업 데이터는 있는데 전체 백업 데이터가 없다면 복원이 불가능하게 됩니다.

혼동하기 쉬운 차등 백업의 특징이 있습니다. 차등 백업은 전체 백업이 이루어지고 난 이후에 변경된 내용을 백업 받는다고 했습니다. 이 사실을 정확히 이해 하셔야 합니다. 다음의 가정을 세우도록 하겠습니다.

고객 테이블에 홍길동 고객정보추가
전체 백업
고객 테이블에 안경태 고객정보 추가
차등 백업
고객 테이블에 김치국 고객정보 추가
차등백업
문제 발생

이렇게 문제가 발생 한 경우 데이터베이스 복원 작업을 하려고 합니다. 과연 이때 필요한 백업 데이터는 어떤것들 일까요?

위 경우 ④ 번의 차등 백업은 안경테 고객의 데이터를 가지고 있습니다. 그리고 ⑥ 번의 차등 백업은 김치국 고객의 정보 뿐만 아니라 안경태 고객의 정보도 가지고 있습니다. 왜냐하면 전체 백업 이후의 변경 데이터를 가지고 있기 때문입니다. 그래서 복원을 원한다면 전체 백업을 복원 한 후 ⑥ 번의 차등 백업을 복원 하면 데이터베이스 복원이 이루어지게 되는 것입니다.

2. 차등 백업 수행

1) EM에서의차등 백업

차등 백업을 받는 방법은 전체 백업을 받는 과정과 동일 합니다. 단지 아래 [그림 1]과 같이 백업 방법을 '데이터베이스 - 차등'으로 선택만 하시면 됩니다. 각 항목들의 의미는 전체 백업과 동일합니다.


[그림 1]

2) T-SQL 문을 이용한 전체 백업

BACKUP DATABASE 문을 이용해서 전체 백업은 물론 차등 백업을 수행 할 수 있습니다. 테이블을 하나 만들어 전체 백업과 차등 백업을 수행하고 그 결과를 보도록 하겠습니다.

[예제 1] Test1 테이블 만들기

CREATE TABLE Test1
(
col1 char(05),
col2 int
)
GO

o 간단한 구조의 테이블 Test1 을 만들었습니다.

[예제 2] 샘플 데이터 추가

INSERT INTO Test1 VALUES('AAAAA',10)
INSERT INTO Test1 VALUES('BBBBB',20)
INSERT INTO Test1 VALUES('CCCCC',30)

o 3개의 레코드를 추가 하였습니다.

[예제 3] 전체 백업 수행

USE Master
GO

BACKUP DATABASE sqlworld TO SQLWORLD WITH INIT

o sqlworld 데이터베이스를 예전에 만든 백업 장치인 SQLWORLD에 전체 백업을 받았습니다.

[예제 4] 샘플 데이터 추가

INSERT INTO Test1 VALUES('DDDDD',40)
INSERT INTO Test1 VALUES('EEEEE',50)
INSERT INTO Test1 VALUES('FFFFF',60)

o 다시 3개의 레코드를 추가 하였습니다.

[예제 5] 첫번째 차등 백업 수행

USE Master
GO

BACKUP DATABASE sqlworld TO SQLWORLD WITH DIFFERENTIAL, NOINIT

o 첫번째 차등 백업을 수행했습니다. NOINIT을 준 이유는 앞에서 백업받은 전체 백업을 보존하기 위해서 입니다. INIT으로 하게 되면 전체 백업 내용이 사라집니다.

[예제 6] 샘플 데이터 추가

INSERT INTO Test1 VALUES('GGGGG',70)
INSERT INTO Test1 VALUES('HHHHH',80)
INSERT INTO Test1 VALUES('IIIII',90)

o 다시 3개의 레코드를 추가 하였습니다.

[예제 7] 첫번째 차등 백업 수행

USE Master
GO

BACKUP DATABASE sqlworld TO SQLWORLD WITH DIFFERENTIAL, NOINIT

o 두번째 차등 백업을 수행했습니다.

3. 차등 백업으로 부터의 데이터베이스 복원

[예제 1] 에서 부터 [예제 7]까지의 과정에서 몇가지 데이터의 변화가 있었고 우리는 전체 백업 한번과 두번의 차등 백업의 과정으로 데이터베이스를 백업 받은 상태입니다. 이 시점에서 문제가 발생하여 sqlworld 데이터베이스를 복원해야 한다고 가정을 하고 복원 작업을 하도록 하겠습니다.

전체 백업으로 부터 복원하는 방법을 이전의 강좌에서 배웠습니다. 동일한 방법으로 sqlworld 데이터 베이스 복원을 시도하게 되면 아래 [그림 2]와같은 화면이 표시됩니다. 빨간색 부분을 보면 위에서 우리가 시도한 3번의 백업 히스토리가 보입니다. 그 중에서 파란색 부분은 두번의 차등 백업 히스토리입니다. [그림 2]에서는 맨 처음 전체 백업과 마지막 차등 백업이 선택되어 있습니다. 이때 전체 백업을 선택하지 않으려고 해도 할 수가 없습니다. 왜냐하먼 차등 백업은 전체 백업 내용이 복원 되어야 의미가 있기 때문입니다.


[그림 2]

위 [그림 2]의 상태에서 [확인] 버튼을 눌러 복원을 하면 전체 데이터가 복원 됩니다. 만일 전체 백업 내용과 첫번째 차등 백업 내용을 선택하고 복원을 하게 되면 Test1 테이블에는 6개의 레코드만 존재하는 상태가 됩니다. 마지막 입력된 3개의 레코드는 복원이 안되기 때문입니다.

========================================================================================

데이터베이스 옵션을 이용한 트렌젝션 로그제어

========================================================================================

1. 트랜잭션(Transaction) 이란?

트랜잭션(Transaction)이란 무언인가에 대하여 다음과 같이 온라인설명서에서는 이야기 하고 있습니다.

트랜잭션은 하나의 논리적 작업 단위로 수행되는 일련의 작업입니다. 작업의 논리적 단위는 ACID(원자성, 일관성, 격리성 및 영속성) 속성이라고 하는 네 가지 속성을 통해 트랜잭션으로서의 자격을 부여합니다.

원자성

트랜잭션은 더 이상 분류할 수 없는 작업 단위여야 하며 모든 데이터 수정 작업이 수행되거나 하나도 수행되지 말아야 합니다.

일관성

완료된 트랜잭션의 모든 데이터는 일관적이어야 합니다. 관계형 데이터베이스에서는 트랜잭션 수정에 모든 규칙을 적용하여 모든 데이터 무결성을 유지해야 합니다. 트랜잭션 마지막에는 B-tree 인덱스 또는 이중 연결 목록 등 모든 내부적 데이터 구조를 반드시 수정해야 합니다.

격리성

동시 트랜잭션에 의한 수정은 다른 동시 트랜잭션에 의한 수정과 격리되어야 합니다. 트랜잭션에서 다른 동시 트랜잭션이 수정하기 전 상태의 데이터를 보거나, 두 번째 트랜잭션이 완료된 후의 데이터를 볼 수는 있지만 중간 상태는 볼 수 없습니다. 결과적으로 시작 데이터를 다시 로드하고 일련의 트랜잭션을 재생하여 원래 트랜잭션이 수행된 후의 상태로 데이터를 되돌릴 수 있는데 이를 순차성이라고 합니다.

영속성

트랜잭션이 완료되고 나면 그 영향이 영구적으로 시스템에 적용됩니다. 수정은 시스템에 오류가 발생한 경우에도 지속됩니다.

이해하기가 상당히 어렵습니다.

로그 백업을 설명하기 위한 것이므로 트랜잭션에 대한 자세한 설명은 하지 않도록 하겠습니다. 이 강좌에서는 트랜잭션이란 데이터를 변경시키는 일련의 행위라고 생각해주시면 되겠습니다. 즉 테이블의 데이터를 수정(Update)하거나 삭제(Delete)하거나 추가(Insert)시키는 행위를 말합니다.

2. 트랜잭션 로그 백업 (Transaction Log Backup) 이란?

트랜잭션 로그 백업(일반적으로 로그 백업이라고 합니다)은 실제 데이터를 백업 받는게 아니고 데이터를 변경시킨 행위 자체를 백업받는것을 이야기 합니다. 예를 들어 고객 테이블에 '홍길동' 고객의 정보가 있는데 이 '홍길동' 고객이 이름이 '홍기동'으로 변경되었다고 한다면 데이터백업은 '홍기동' 이라는 데이터를 백업 받는 것이고 로그 백업은 '홍길동'의 이름이 '홍기동'으로 바뀌었다는 사실을 백업받은 것입니다. 만일 데이터에 문제가 생기는 이름을 바꾼 행위를 재수행 함으로써 데이터를 복원하게 됩니다.

SQL 서버는 관리자가 로그를 지우라는 설정을 하지 않는 한 문제 발생시 트랜잭션을 취소하거나 데이터베이스에 반영되지 않은 트랜잭션을 반영하기 위한 목적으로 로그를 남기게 됩니다. 이렇게 남는 로그는 관리자 입장에서 볼 때는 불의의 사태로부터 데이터를 복구 시킬 수 있는 중요한 수단이 됩니다.

또한 로그 백업은 데이터베이스의 사이즈가 너무 커서 데이터베이스 전체를 백업받기가 어려울 때 데이터의 손실을 막기 위한 또다른 백업 방법으로서 사용됩니다.

3. 로그에 대한 데이터베이스 설정

다음과 같은 내용을 데이터베이스 설정을 통하여 구현할 수 있습니다.

o트랜잭션 로그가 쌓이지 않게 하기
o 트랜잭션 로그가 쌓이게 하기
o 로그 파일의 사이즈가 무작정 커지지 않게 하기

1) 트랜잭션 로그가 쌓이지 않게 하기

트랜잭션 로그가 쌓이지 않게 하는 것은 실제 업무에서는 사용하지 않는게 좋습니다. 로그가 쌓이지 않게 하면 로그 파일이 무작정 증가하는 사태를 막을 수는 있으나 만일의 경우에 중요한 복구가 불가능 할 수 있기 때문입니다. 제 개인적인 생각으로는 시스템을 개발하는 동안에 테스트용 데이터가 기록되는 과정에서는 로그가 쌓이지 않게 설정을 해서 작업을 하고 실제 업무에 반영이 되는 시점에서는 로그가 쌓이게 하는게 좋습니다. 로그가 쌓이게 되면 관리자는 로그 백업을 이용해서 로그 사이즈가 계속 증가하는 사태를 막아야 합니다. (이에 대해서는 뒤에서 살펴보도록 하겠습니다)

로그가 쌓이지 않게 하기 위해서는 데이터베이스 복구 모델을 '단순(Simple)'로 하면 됩니다. SQL 서버 7.0의 경우는 데이터베이스 옵션 중에서 'trunc. log on chkpt' 옵션이 있는데 SQL 서버 2000에서는 복구모델을 이용해서 이 기능을 대신하게 됩니다. 물론 이전 버젼과의 호환을 위해서 'trunc. log on chkpt' 을 지정해주어도 되나 결과는 같습니다.

① 해당 데이터베이스 위해서 마우스 오른쪽 버튼을 눌러 표시되는 단축메뉴에서 [등록정보]를 선택하여 데이터베이스 등록 정보를 표시합니다.

② 다음 [그림 1]은 데이터베이스 옵션에서 복구모델을 '단순(Simple)'로 한 예입니다.


[그림 1]

복구 모델은 '단순' 으로 하게되면 커밋(Commit) 된 트랜잭션의 로그는 자동으로 제거되어 로그가 쌓이지 않게 됩니다.

만일 데이터베이스 복구 모델을 QA에서 변경하고자 하는 경우는 다음과 같이 ALTER DATABASE 를 이용하시면 됩니다.

USE Master
GO

ALTER DATABASE Sqlworld SET RECOVERY SIMPLE

o SIMPLE 위치에는 FULL 또는 BULK_LOGGED 가 지정될수 있습니다.

※ 복구 모델에 대한 자세한 설명을 원하시면 온라인설명서(Books Online)에서 '복구 모델'을 찾아보시기 바랍니다.

2) 트랜잭션 로그가 쌓이게 하기

로그가 쌓이게 하려면 위 [그림 1]에서 복구 모델을 '단순'이 아닌 '최대' 또는 '대량로그' 로 하시면 됩니다. 로그가 쌓이게 되면 로그가 증가함에 따라 로그 파일이 자동으로 증가하게 됩니다. (물론 데이터베이스 생성시 자동증가로 설정한 경우) 그러므로 이를 방치하게 되면 로그 파일이 무작정 증가하여 전체 하드디스크 공간을 차지하게 되는 경우가 있습니다. 실제 데이터베이스의 사이즈는 500MB인데 로그 사이즈는 50GB가 되는 경우도 있습니다.

로그 파일의 사이즈가 무작정 증가하지 않도록 하기 위해서는 정기적으로 로그 파일을 백업받아 주어야 합니다. 로그 백업은 만일의 경우에 대비해서 로그를 별도로 기록해주는 목적과 로그 사이즈를 줄여주는 목적 두가지를 가지고 있습니다.

로그 백업에 대해서는 다음 강좌에서 곧바로 다룰 것입니다. 우선 로그 사이즈 증가를 방지하기 위한 데이터베이스 옵션 설정에 대하여 살펴보도록 하겠습니다.

3) 로그 파일의 사이즈가 무작정 커지지 않게 하기

로그가 무작정 쌓이는 것은 백업을 통해서 방지 할 수 있다고 했습니다. 하지만 엄청난(?) 트랜잭션에 의해 발생된 로그로 인하여 로그 파일의 사이즈가 커진 상태에서 로그를 백업 받게 되면 로그는 줄어드나 커져버린 로그 파일의 사이즈는 별도의 설정이 없으면 자동으로 줄어들지 않게 됩니다.

로그 파일의 사이즈를 SQL 서버가 수시로 확인하여 불필요하게 커진 경우 그 안에 로그가 없으면(백업으로 인해) 로그 파일의 사이즈를 자동으로 줄어들게 할 수 있습니다. 이러한 설정은 데이터베이스의 '자동 축소' 옵션을 이용함으로써 가능합니다. 아래 [그림 2]은 '자동축소' 옵션을 선택한 화면의 예입니다.


[그림 2]

4. 정리

다음의 내용을 필히 기억해 주시기 바랍니다.

o 트랜잭션 로그는 만일의 사태에서 데이터 복구를 가능하게 하는 중요한 의미를 가지고 있어 함부로 지워서는 안됩니다.
o 실제 업무에서 데이터베이스를 사용 하는 경우는 데이터베이스 복구 모델을 '최대' 또는 '대량로그'로 설정하여 로그가 지워지지 않고 쌓이게 합니다.
o 쌓이는 로그를 정기적으로 백업 받아 로그가 꽉 차는 사태를 방지해야 합니다.
o 백업 받아 빈공간이 많아진 로그 파일을 자동으로 축소하기 위해서는 데이터베이스 옵션 중에서 '자동축소'를 선택하시면 됩니다.
o 자동 축소가 아닌 경우는 DBCC SHRINKDATABASE 또는 DBCC SHRINKFILE을 이용해서 수작업으로 축소시켜 주어야 합니다.

현재 자신이 사용하고 있는 데이터베이스의 옵션을 살펴보고 복구모델은 어떻게 되어 있는지, 로그 백업은 어떻게 이루어지고 있는지 확인을 해보시기 바랍니다.

다음 강좌에서는 로그 백업을 받는 방법을 살펴보고 증가된 로그를 백업받고 축소시켜주는 내용을 실습해 보고자 합니다.

========================================================================================

트렌젝션로그 줄이기 테스트

========================================================================================

1. 테스트를 위한 임시 테이블 만들기와 데이터 추가하기

예전의 테스트 처럼 sqlworld 데이터베이스를 이용하여 실제 상황을 재현해 보도록 하겠습니다. 현재 sqlworld 데이터베이스의 옵션은 다음과 같습니다.

o 데이터베이스 복구모델 : 최대
o 자동 축소기능 : 사용안함

다음 [그림 1]은 현재 sqlworld의 데이터베이스와 로그 사이즈를 보여줍니다.


[그림 1]

우선 현재의 sqlworld 데이터베이스를 백업 받도록 하겠습니다.(모든 백업의 기본은 전체 백업입니다)

USE Master
GO

BACKUP DATABASE sqlworld TO DISK = 'E:\Data\sqlworld.bak'

1) 테이블 만들기

다음과 같이 테스트 테이블 Test_Log를 만들도록 하겠습니다.

USE sqlworld
GO

CREATE TABLE Test_Log
(
col1 int PRIMARY KEY,
col2 char(1000)
)

다음과 같이 스크립트를 이용해서 레코드를 추가하도록 하겠습니다.

SET NOCOUNT ON
GO

DECLARE @num int
SET @num = 1
WHILE @num < 5001
BEGIN
INSERT INTO Test_Log VALUES(@num, REPLICATE('A',1000))
SET @num = @num + 1
END

위 작업을 통해서 오천개 정도의 레코드가 Test_Log 테이블에 추가되었습니다. 이로 인하여 sqlworld 데이터 사이즈와 로그 사이즈가 증가했습니다. 아래 [그림 2]가 그 내용을 확인해주고 있습니다.


[그림2]

만일 sqlworld 데이터베이스 복구 모델이 '단순' 이었다면 위와 같은 작업이 완료가 되면 로그가 자동으로 제거되어 [그림 2] 처럼 로그 사이즈가 증가하지 않을 것입니다.(이 내용이 잘 이해되지 않으면 바로 이전의 강좌를 다시한번 읽어보시기 바랍니다)

2) 데이터를 변경하여 데이터와 로그 사이즈 증가시키기

다음과 같이 데이터를 변경하고 삭제하여 로그 사이즈를 증가시켜 보겠습니다.

UPDATE Test_Log Set col2 = REPLICATE('B',1000) WHERE col1 < 1000
GO
DELETE FROM Test_Log WHERE col1 < 2000
GO
DELETE FROM Test_Log WHERE col1 < 4000

위 작업을 수행하니 Test_Log 테이블의 데이터 변경에 대한 로그와삭제에 대한 로그가 증가함에 따라 sqlworld 데이터베이스의 사이즈는 다음 [그림 3]과 같이 변하였습니다.


[그림3]

로그 파일은 0.99 MB에서 6.74 MB 로 사이즈가 증가함을 알 수 있습니다.

이처럼 트랜잭션이 발생함에 따라 로그가 계속 쌓이면서 로그 파일의 사이즈가 계속 증가함을 알 수 있습니다. 이제 확인할 내용은 로그 백업을 하면 로그가 줄어드는지, 그리고 로그 파일의 사이즈는 어떻게 되는지 하는 것입니다.

2. 트랜잭션 로그 백업을 통한 로그 줄이기

로그 백업은 예전에 배운 데이터베이스 백업과 비슷한 방법으로 이루어 집니다. EM을 통해서 할 수도 있고 QA에서 직접 BACKUP LOG 문을 이용하여 백업 받을 수도 있습니다. 이 테스트에서는 QA를 이용하여 현재 sqlworld 데이터베이스의 로그를 백업받도록 하겠습니다.

USE Master
GO

BACKUP LOG sqlworld TO DISK = 'E:\Data\sqlworld_log.bak'

수행하는 방법은 BACKUP DATABASE 문과 비슷합니다.

만일 로그를 백업 받지는 않고 단지 현재의 로그만 지우고 싶으면 다름과 같이 TRUNCATE_ONLY 옵션을 사용하면 됩니다.

USE Master
GO

BACKUP LOG WITH TRUNCATE_ONLY

이렇게 로그를 백업 받은 후의 sqlworld 데이터베이스의 사이즈를 보니 다음 [그림 4]와 같이 변한 것을 볼 수 있습니다.


[그림4]

로그 사이즈가 3.64 MB 에서 1.84 MB로 줄어 들었습니다. 하지만 로그 파일의 사이즈는 아직도 6.74 MB로서 원래 사이즈를 그대로 유지하고 있습니다. 결국 4.9 MB의 빈 공간이 놀고(?) 있게 됩니다.

3. DBCC SHRINKDATABASE을 이용한 로그파일 사이즈 줄이기

DBCC SHRINKDATABASE 을 이용해서 수작업으로 비어있는 로그 사이즈를 없애서 로그 파일의 사이즈를 축소해 보도록 하겠습니다.

USE Master
GO

DBCC SHRINKDATABASE(Sqlworld)

결과는 다음 [그림 5]와 같이 변한것을 알 수 있습니다.


[그림5]

로그 파일의 사이즈가 [그림 4]와 비교 할 때 6.74 MB에서 2.49 MB로 줄어든 것을 알 수 있습니다. DBCC SHRINKDATABASE에 의해 줄어드는 로그 파일의 사이즈는 실제 데이터 파일의 빈 공간이 많을 수록 효과가 좋습니다. DBCC SHRINKDATABASE 또는 DBCC SHRINKFILE에 대한 내용은 이전의 데이터베이스에 대한 강좌를 참고해 주시기 바랍니다.

4. 정리

로그 파일 사이즈 문제를 가지고 질문을 하시는 경우가 상당히 많습니다. 지금까지 설명드린 내용이 도움이 되었으면 합니다. 데이터베이스 관리자는 항상 로그 파일에 대한 관심을 가지고 모니터링을 해야 합니다. 하드디스크의 여유 공간은 충분한지도 수시로 확인하셔야 합니다. 그렇지 않으면 TempDB가 꽉 찼다는 등의 오류가 발생하게 됩니다.

========================================================================================

백업과 복원 정리

========================================================================================

이번 강좌에서는 복원에 대한 전체적인 내용을 살펴 보도록 하겠습니다. 즉, 전체 백업과 차등 백업 및 로그 백업을 받은 상태에서 복원을 하는 순서와 방법을 살펴보게 됩니다.

1. 테스트를 위한 임시 테이블 만들기와 데이터 추가하기

우선 현재의 sqlworld 데이터베이스에 테스트 테이블을 만들고 백업을 받도록 하겠습니다.

1) 테이블 만들기

다음과 같이 테스트 테이블 Test_Log를 만들도록 하겠습니다.

USE sqlworld
GO

CREATE TABLE Test1
(
col1 int,
col2 char(05)
)
GO

2) 데이터 추가하기

다음과 같이 스크립트를 이용해서 레코드를 추가하도록 하겠습니다.

INSERT INTO Test1 VALUES(1,'AAAAA')
INSERT INTO Test1 VALUES(2,'BBBBB')
INSERT INTO Test1 VALUES(3,'CCCCC')
INSERT INTO Test1 VALUES(4,'DDDDD')
INSERT INTO Test1 VALUES(5,'EEEEE')
GO

위 작업을 통해서 다섯개의 레코드가 Test1 테이블에 추가되었습니다.

2. 데이터베이스 백업

1) 데이터베이스 백업을 위한 백업 장치 만들기

다음과 같이 데이터베이스를 백업 받기 위한 백업 장치를 만들도록 하겠습니다.

EXEC sp_addumpdevice 'disk', 'sqlworld_dump', 'E:\Data\sqlworld_dump.bak'
GO

※ 백업 장치 만드는 방법에 대해서 이해하고 있지 못하신 분들은 예전에 진행된 백업 장치 만들기 강좌를 참고하여 주시기 바랍니다.

2) 데이터베이스 전체 백업

앞에서 만든 sqlworld_dump 백업 장치에 현재까지의 sqlworld 데이터베이스를 전체 백업 받도록 하겠습니다.

BACKUP DATABASE sqlworld TO sqlworld_dump WITH INIT
GO

이 전체 백업 작업으로 인해서 다섯개의 레코드가 추가된 Test1 테이블이 백업된 것을 알 수 있습니다.

※ 전체 백업에 대해 이해하고 있지 못하신 분들은 예전에 진행된 전체 백업 받기강좌를 참고하여 주시기 바랍니다.

3) 데이터 추가하기

다음과 같이 스크립트를 이용해서 다섯개의 레코드를 더 추가하도록 하겠습니다.

INSERT INTO Test1 VALUES(6,'FFFFF')
INSERT INTO Test1 VALUES(7,'GGGGG')
INSERT INTO Test1 VALUES(8,'HHHHH')
INSERT INTO Test1 VALUES(9,'IIIII')
INSERT INTO Test1 VALUES(10,'JJJJJ')
GO

위 작업을 통해서 다섯개의 레코드가 Test1 테이블에 추가되었습니다. 이제 Test1 테이블에는 col1 컬럼이 1 에서 10까지의 값을 갖는 열개의 레코드가 기록되어 있습니다.

4) 데이터베이스 차등 백업

앞에서 만든 sqlworld_dump 백업 장치에 현재까지의 sqlworld 데이터베이스를 차등 백업 받도록 하겠습니다.

BACKUP DATABASE sqlworld TO sqlworld_dump WITH DIFFERENTIAL
GO

이 차등 백업에 의해 앞의 3) 번에서 이루어진 다섯개의 레코드를 추가한 내용이 백업되었습니다.

※ 전체 백업에 대해 이해하고 있지 못하신 분들은 예전에 진행된 차등백업 받기 강좌를 참고하여 주시기 바랍니다.

5) 데이터 또 추가하기

다음과 같이 스크립트를 이용해서 다섯개의 레코드를 더 추가하도록 하겠습니다.

INSERT INTO Test1 VALUES(11,'KKKKK')
INSERT INTO Test1 VALUES(12,'LLLLL')
INSERT INTO Test1 VALUES(13,'MMMM')
INSERT INTO Test1 VALUES(14,'NNNNN')
INSERT INTO Test1 VALUES(15,'OOOOO')
GO

위 작업을 통해서 다섯개의 레코드가 Test1 테이블에 추가되었습니다. 이제 Test1 테이블에는 col1 컬럼이 1 에서 10까지의 값을 갖는 열개의 레코드가 기록되어 있습니다.

6) 데이터베이스 차등 백업

앞에서 만든 sqlworld_dump 백업 장치에 현재까지의 sqlworld 데이터베이스를 차등 백업 받도록 하겠습니다.

BACKUP DATABASE sqlworld TO sqlworld_dump WITH DIFFERENTIAL
GO

이 차등 백업에 의해 앞의 3)번과 5) 번에서 이루어진 열개의 레코드를 추가한 내용이 백업되었습니다.

7) 데이터 변경

다음과 같이 스크립트를 이용해서 col1 컬럼이 6보다 작은 다섯개의 레코드에 대하여 col2 컬럼을 전부 'XXXXX' 로 변경하였습니다.

UPDATE Test1 SET col2 = 'XXXXX' WHERE col1 < 6
GO

8) 트랜잭션 로그 백업

7) 번에서 이루어진 변경 처리를 로그 백업을 받도록 하겠습니다. 로그 백업을 위해 새로운 백업장치 sqlworld_log_dump 를 만들어 이 장치에 로그를 백업 받도록 하겠습니다.

EXEC sp_addumpdevice 'disk', 'sqlworld_log_dump', 'E:\Data\sqlworld_log_dump.bak'
GO

BACKUP LOG sqlworld TO sqlworld_log_dump WITH INIT
GO

9) 데이터 추가 변경 (문제 발생)

다음과 같이 스크립트를 이용해서 col1 컬럼이 5보다 큰 코드에 대하여 col2 컬럼을 전부 'YYYYY' 로 변경하였습니다.

UPDATE Test1 SET col2 = 'YYYYY'
GO

앗! WHERE 절을 적지 않아서 모든 레코드의 col2 컬럼이 'YYYYY'로 바뀌어 버렸습니다.

3. 현재까지 백업된 내용 정리

지금까지 이루어진 4번의 백업 작업에 의해 Test1 테이블에 대해서는 다음과 같은 내용이 백업되었습니다.

1) 전체 백업 : col1 컬럼에 1 부터 5 까지 다섯개의 레코드
2) 첫번째 차등 백업 : col1 컬럼에 6 부터 10 까지 다섯개의 레코드
3) 두번째 차등 백업 : col1 컬럼에 6 부터 15 까지 열개의 레코드
4) 로그 백업 : col1 컬럼이 6 보다 작은 다섯개의 레코드에 대해 col2 컬럼을 'XXXXX' 로 변경 한 행위

4. T-SQL을 이용한 데이터베이스 복원

현재의 상황에서 앞에서 수행되었던 모든 백업을 복원하여 col2 컬럼이 'YYYYY'로 바뀐 사태를 수습하도록 하겠습니다.

1) 전체 백업 복원

USE master
GO

RESTORE DATABASE sqlworld FROM sqlworld_dump WITH FILE =1, NORECOVERY
GO

o NORECOVERY 옵션으로 전체 백업 받은 내용을 복원 했습니다.
o FILE = 1은 sqlworld_dump 백업 장치에 여러 가지 백업(한번의 전체 백업과 두번의 차등 백업)이 있으므로 이 중에서 첫번째, 즉 전체 백업을 선택한다는 의미입니다.

2) 차등 백업 복원

RESTORE DATABASE sqlworld FROM sqlworld_dump WITH FILE = 3, NORECOVERY
GO

o NORECOVERY 옵션으로 차등백업 받은 내용을 복원 했습니다.
o FILE = 3 은 sqlworld_dump 백업 장치에 여러 가지 백업(한번의 전체 백업과 두번의 차등 백업)이 있으므로 이 중에서 세번째, 즉 두번째의 차등 백업을 선택한다는 의미입니다.
o 결국 첫번째의 차등 백업은 사용될 필요가 없습니다.

3) 로그 백업 복원

RESTORE LOG sqlworld FROM sqlworld_log_dump WITH RECOVERY
GO

o 로그 복원이 복원의 마지막 단계 이므로 RECOVERY 옵션을 사용하였습니다.

5. 과제

다음의 내용을 구현해 보시기 바랍니다.

1) 위에서 T-SQL로 구현한 복원을 EM(Enterprise Manager)를 이용해서 구현해 보세요.
2) 첫번째 차등 백업, 즉 col1 컬럼이 1부터 10까지만 가지고 있는 내용을 복원해 보세요.

부족한 부분은 관련된 강좌를 다시한번 확인하신 후 처리해 보시기 바랍니다.

Posted by 1010
02.Oracle/DataBase2010. 10. 29. 11:17
반응형
Posted by 1010
02.Oracle/DataBase2010. 8. 20. 14:39
반응형
SELECT  NULL + 100 FROM DUAL; 의 결과는 무엇일까요?

NULL과 사직연산을 하게되면 결과 값은  NULL이 됩니다.

그래서 SELECT NVL(NULL, 0) + 100 FROM DUAL; 과 같이 NULL 공포에서
벗어 나려고 NVL 함수를 자주 사용하게 됩니다.

근본적으로 컬럼값에 NULL이 없게 NOT NULL로 설계 했다면 NVL를 남발하는 일을
없었겠죠. ㅎㅎ

그리고 또하나 NULL이 포함된 컬럼에 그룹함수( SUM() ) 를 사용하면 어떻게 될까요?

SUM를 포함한 그룹함수에서는 NULL 컬럼을 자동으로 건너띄므로 NULL 값이 있다고
해서 전체 결과가 NULL로 변해 버리지 않습니다. 즉 NVL 함수를 사용할 필요가 없다는
것입니다.

NVL() 도 함수임으로 자주 콜하게 되면 부하가 생기겠죠. 설계에서부터 NULL이 나오지
않게 하고 그룹함수는 NVL를 사용할 필요가 없으니 굳이 넣어서 부하를 줄 필요가 없겠죠. . .


출처 : http://dev4u.tistory.com/184
Posted by 1010
02.Oracle/DataBase2010. 8. 16. 08:41
반응형
http://kr.forums.oracle.com/forums/thread.jspa?threadID=1038232

problem whle starting the SOA server.
게시일: 2010. 3. 3 오후 10:49
 
     
Hi,

I have Installed Oracle SOA suite in a server. I have created a domain and with in that domain, there is Admin server, Soa server and BAM server. They were working fine. But when I tried to re-start them recently , the Admin server was showing the warning

<Mar 3, 2010 10:42:58 PM PST> <Warning> <JDBC> <BEA-001129> <Received exception while creating connection for pool "mds-SpacesDS": ORA-28001: the password has expired>

but still I am able to access teh web logic console of the admin server.

When I try to start the SOA server it gives the message

Internal Exception: weblogic.jdbc.extensions.ConnectionDeadSQLException: weblogic.common.resourcepool.ResourceDeadException: 0:weblogic.common.ResourceException: Could not create pool connection. The DBMS driver exception was: ORA-28001: the password has expired

The same is the case with the BAM server also . The console of BAM server is showing the message

Internal Exception: weblogic.jdbc.extensions.ConnectionDeadSQLException: weblogic.common.resourcepool.ResourceDeadException: 0:weblogic.common.ResourceException: Could not create pool connection. The DBMS driver exception was: ORA-28001: the password has expired.

I have used SYSTEM user credentials while installaing the SOA-SUITE. I have changed and re-set the password for that user. But That did not help.

can any one please let me know how this issue can be resolved. Please contact me if any more info is needed.

Thanks in advance for your time,
Raj Kumar
Anuj Dwivedi, TCS

글: 2,440
등록일: 08-10-29
Re: problem whle starting the SOA server.
게시일: 2010. 3. 3 오후 11:44   Raja Kumar님의 질문에 답변 Raja Kumar님의 질문에 답변
유용함
      댓글
Hi Raj,

Have you created any connection pool with name "mds-SpacesDS"?

ORA-28001: the password has expired

Above error shows that account of username, used in the DataSource of connection pool "mds-SpacesDS", has expired and password should be changed. After changing the pasword of DB user, mention the same in your Data-Source as well. Update the DBAdapter to refresh the connection pool.

Regards,
Anuj
Raja Kumar

글: 36
등록일: 08-12-04
Re: problem whle starting the SOA server.
게시일: 2010. 3. 4 오전 5:15   Anuj Dwivedi, TCS님의 질문에 답변 Anuj Dwivedi, TCS님의 질문에 답변
 
      댓글
Anuj,

Thanks for the reply.

This connection pool seems to have got created during the installation of SOA-suite.

Can you please tell me how can I findout the username of the Databse for which the password needs to be changed, sothat I can update the pwd and reflect that change in the DB Adpater configuration and the Datasource.

Thanks,
Raj Kumar
Raja Kumar

글: 36
등록일: 08-12-04
Re: problem whle starting the SOA server.
게시일: 2010. 3. 4 오전 6:00   Raja Kumar님의 질문에 답변 Raja Kumar님의 질문에 답변
 
      댓글
Hi,

Posted by 1010
02.Oracle/DataBase2010. 6. 24. 09:44
반응형
ORACLE에서 문자열을 비교하기 위해 Blank-Padded Comparison Semantics 과Nonpadded Comparison Semantics 이라는 방법을 사용한다. 여기에서 주의할 점은 Blank-Padded Comparison Semantics과 Nonpadded Comparison semantics의 결과가 항상 일치하는 것이 아니라는 점이다.

그러면 사례를 통해 두 비교방식에 대하여 알아보도록 하자.

Blank Padded Comparison
Nonpadded Comparison

'ab' > 'aa'
'ab' > 'aa'

'ab' > 'a '
'ab' > 'a '

'ab' > 'a'
'ab' > 'a'

'ab' = 'ab'
'ab' = 'ab'

'a ' = 'a'
'a ' > 'a'


위의 사례를 보면 비교되는 문자열이 Blank를 포함하고 있으면 padding과 non padding이 다른 결과를 나타내고 있다.

1.Blank-Padded Comparison Semantics

비교되는 두 값이 서로 다른 길이를 가질 경우에 길이가 짧은 쪽에 공백을 추가하여 길이를 동일하게 한다.
서로 다른 문자 값이 나타날 때까지 문자 단위로 비교를 수행한다.
서로 다른 값이 나타나면 문자 값이 큰 컬럼이 크다고 판단하고 비교를 종료한다. 그러나 서로 다른 값이 나타나지 않으면 중간에 어떤 유효한 값이 나타날 지를 알 수가 없기 때문에 끝까지 비교를 하게 된다. 만약 끝까지 비교를 하고도 다른 문자가 나타나지 않으면 같다고 판단한다.
Oracle에서 이 비교방식을 사용하는 경우는 다음과 같다.

양쪽 모두가 CHAR 혹은 NCHAR 타입인 경우
양쪽 모두가 문자타입의 상수일 경우
사용자 함수에서 반환된 값
2.Nonpadded Comparison Semantics

서로 다른 문자 값이 나타날 때까지 문자 단위로 비교를 수행한다.
서로 다른 값이 나타나면 문자 값이 큰 컬럼이 크다고 판단하고 비교를 종료한다. 만약 값이 같다면 길이가 짧은 컬럼만큼만 비교한 후 각 컬럼의 길이를 비교하여 길이가 긴 컬럼이 크다고 판단한다.
Oracle에서 이 비교방식을 사용하는 경우는 다음과 같다.

비교되는 값 중에 VARCHAR2 혹은 NVARCHAR2가 있을 경우 

[출처] Oracle의 문자열비교|작성자 짱가

Posted by 1010
02.Oracle/DataBase2010. 6. 16. 10:32
반응형

Ⅰ. Index 

인덱스는 테이블이나 클러스터에서 쓰여지는 선택적인 객체로써, 오라클 데이터베이스 테이블내의 원하는 레코드를 빠르게 찾아갈 수 있도록 만들어진 데이터 구조입니다. 인덱스는 일련의 엔트리 목록으로 구성되어 있으며, 이러한 엔트리는 테이블의 테이타 행에 사용되는 각각의 키값과 ROWID값을 가집니다. 따라서 특정한 값에 대해 ROWID값을 가지고 접근 하기 때문에 접근속도가 상당히 빠릅니다. 인덱스는 여러 가지 방법으로 구현될 수 있으나 오라클에서는 B*Tree기반의 인덱스를 사용합니다. 왜 이렇게 인덱스에 관해서 장황하게 설명하냐구요? 앞으로 나오는 거의 대부분의 튜닝 과정속에서 index가 중요하게 사용되기 때문입죠. 아울러 어떤이는 “가장 최적의 인덱스를 어떻게 구성할 것인가는 수 많은 애플리케이션을 잘 작성하는 것보다 훨씬중요하다.”라고 하더군요. 인덱스의 ROWID는 16진수 문자열로 표현된 테이블 데이터의 실제 메모리의 물리적인 주소를 저장하고 있는 데이터 타입을 말합니다. 아래는 인덱스를 생성하는 형식입니다.

CREATE [UNIQUE] INDEX index 

        ON table ( 

                column [ASC | DESC], .... 

        ) 

        [CLUSTER cluster] 

        [INITRANS int] 

        [MAXTRANS int] 

        [TABLESPACE tablespace] 

        [STORAGE storage_clause] 

        [PCTFREE int] 

        [NOSORT] 

여기서 column은 인덱스를 생성할 컬럼명을 뜻합니다. 인덱스 생성시 B*Tree의 키 값이 되겠죠,

따라서 SQL문에서 특정 column을 찾고자 할 때 이 키를 가지고 B*Tree 찾게 되므로 중요한 값입니다. 물론 index적용여부 또한 이 키가 결정 할 수도 있으니 키 선정에 많은 신경쓸 필요가 있겠군요. 뒤에서 인덱스 키를 선택하는 방법과 이를 이용한 쿼리 성능 향상 방법에 대해 다룹니다.

따라서 index가 생성되어 있는 경우 이 index를 이용한 검색은 물리주소를 직접 엑세스하기 때문에 일반검색에 비해 훨씬 빠른 속도를 냅니다. 그러니 우리에 목적은 얼마나 잘 이 index를 이용해 검색하느냐가 되겠지요. 그럼 바로 SQL문에서 index를 타지 못하는 경우를 살펴보겠습니다. 여기서 인덱스를 탄다고 하는 말은 인덱스를 이용한 검색이 실행됨을 뜻합니다. 다만 넓은 범위 처리시에는 테이블로의 랜덤 액세스가 증가하여 인덱스를 타는 경우 성능이 저하되기도 합니다. 그러한 경우는 clustering 적용을 검토해 봐야할듯 합니다. 그럼 인덱스를 사용할때 좋은 성능을 내는데도 불구하고 인덱스를 사용하지 못하게 되는 경우를 살펴보겠습니다.

 ◦ 인덱스 사용이 안되는 경우

1) index column이 변형되어 인덱스를 타지 못하는 경우

[예] select * from dept where substr(dname, 1, 3)='abc'; 

여기에서 인덱스로 사용 되어야 할 dname column이 함수로 인해 변형되어, index를 이루는 값을 찾지 못하여 full scan이 발생하는 경우입니다. 여기서 full scan이라함은 테이블의 처음부터 끝까지 순차적인 탐색이 일어나는 것을 뜻합니다. 정확히는 full rage scan이 맞으나 full scan이란 용어도 많이 쓰이므로 구분 없이 쓰겠습니다.

2) index column으로 사용될 column의 값이 부정형인경우 index타지 못한다. 

[예] select * from tmp where job<>'sales'; 

이 경우 역시 B*Tree에서 찾고자 하는 값이 아예 없으므로 인덱스를 타지 못하겠죠.

3)찾을 키가 NULL 혹은 NOT NULL의 경우 index를 타지못한다. 

[예] select * from emp where ename is NOT NULL; 

여기서 NULL인 경우 index는 만들어 지지만 key column엔 첨가되지 못하므로 index를 타지 못합니다, NOT NULL인 경우는 B*Tree에서 찾고자하는 키가 없으므로 역시 index를 타지못합니다. 

4)Optimizer의 취사선택으로 index scan이 발생되지 않는 경우 (‘7890‘만 인덱스로 생성된 경우) 

[예] select * from emp where job like 'ab%' and empno='7890'; 

이 경우는 SQL문이 해석되고 실행되는 과정에서 optimizer가 비용(여기선 탐색시간 혹은 응답시간 등)이 적게드는 키 값을 선택하여 그것을 기본으로 하여 다른 키 값을 찾기 때문에 (이것을 ‘경로를 선택한다’라고 합니다.) 위의 예에선 ‘ab%’에 해당하는 column이 테이블내에서 특정한 부분에 집중되어 있는 경우 optimizer가 이 column을 선택 할 경우 index를 타지 못하게 됩니다.

일단 이러한 경우만 피해간다고 하면 index사용시 상당한 효과를 볼 수 있겠습니다. insert, update, delete시 인덱스를 재구성해야하기 때문이죠 index도 서버에겐 하나의 overhead입니다. 그것을 어떤 상황에 맞게 구성하고 사용하는 것이 중요하겠죠.

 그러면 위와 같은 쿼리문이 꼭 필요한 경우에 인덱스를 적용시키고자 할 경우엔 어떻게 해야 될까요? “인덱스 타도록 강제로 지정해 주면 되지”하시면 정답입니다. 그럼 각각의 경우 어떻게 해결 할지 차례대로 살펴보겠습니다.

 ◦인덱스 미사용 해결

1) index column에 외부적(external)인 변형이 이루어진 경우

◦select * from dept where substr(dname, 1, 3)='abc';

→select * from dept where dname like "abc%";

◦select * from emp where sal*12=1200000;

→select * from emp where sal=1200000/12;

◦select * from emp where TO_CHAR(HIREDATE,'YYMMDD')='940101';

→select * from emp HIREDATE=TO_DATE('940101','YYMMDD');

◦select * from emp where job like 'ab%' and empno='7890';

→??? 앞서 말씀 드렸듯이 이경우는 데이터의 전체적인 분포를 알아야만 optimizer가 어떤 것을 선택 할지 예상이 가능하므로 테이블에 대한 지식이 우선해야 겠습니다.


◦select * from emp where empno between 100 and 200 and NVL(job, 'x')='clerk';

→select * from emp where empno between 100 and 200 and job='clerk';


◦select * from emp where deptno || nob='10salesman'; 

→select * from emp where deptno='10' and job='salesman'; 


[예외] 어디에나 그렇듯이 예외도 있습니다. 여기서 예외란 인덱스를 타지 않도록 만드는 경우가 인덱스를 타는 경우보다 빠른 SQL문을 말합니다. 이러한 방법을 사용하실 때엔 테이블 전체적인 데이터 분포도나 많이 사용되는 쿼리 종류라든지 혹은 자주 검색되는 데이터의 종류 등의 것에 대한 지식이 요구됩니다. 한마디로 테이블을 꿰고 있어야 된다는 말씀. 이러한 경우 index 적용을 피하게 하는 방법을 ‘의도적인 suppressing’ 이라합니다. 

[예]

◦select * from emp where job='manager'; 

→select * from emp where RTRIM(job)='manager'; 

여기서 job이 index로 구성 되있는 경우이고, 사람들이 입력시 왼쪽이나 오른쪽에 공백을 많이 입력하는 경우라면 굳이 index를 타는 것이 full scan보다 빠를 순 없습니다. 따라서 이러한 경우라면 full scan이 빠르겠죠. 


2) index column의 내부적(internal)인 변형시

앞서 살펴보았던 외부적인 변형들의 경우 대개 탐색을 위한 ‘키’값의 변형을 줄이는 방법이 많았던 반면 내부적인 변형은 바로 전에 보았던 suppressing이 주류를 이룹니다. 그럼 예를 보도록 하죠. 

테이블의 구조가 다음과 같다고 하고 아래의 예를 보시기 바랍니다. 

[테이블] 

create table samplet( 

        chr char(10), 

        num nubmer(12,3), 

        var varchar2(20), 

        dat date); 

◦select * from samplet where chr=10; 

→select * from samplet where TO_NUMBER(cha)=10; 

◦select * from samplet where num like '9410%'; 

→select * from samplet where TO_CHAR(num) like '9410%'; 

◦select * from samplet where dat='01-JAN-94'; 

→select * from samplet where dat=TO_DATE('01-JAN-94'); 

왜 설명 안하냐구요? 한번에 몽땅하겠습니다. suppressing의 경우 몇가지 기준이 있습니다. 대개의 경우 아래의 룰을 이용하시면 되겠습니다. 

변경 전 형식 
 변경 후 형식 
 
number=character
 TO_CHAR(number)=character
 
character=number
 TO_NUMBER(character)=number
 
date=character
 date=TO_DATE(character)
 

3) NOT Operator의 경우

◦select 'Not fount!' into :col1 from emp where empno<>'1234'; 

→select 'OK' into:col1 from emp where NOT EXISTS ( 

        select * from emp where empno='1234') 

여기에선 서브쿼리를 이용하여 키를 포함 하는 튜플들을 제외한 값들을 가져오게끔 변형한 예입니다. 이는 검색에 사용되는 키가 not operator인 경우 변형 할 수 있는 한가지 방법이 되겠습니다. 

◦select * from emp where ename like '김%' and job <> 'sales'; 

→(1)select * from emp where ename like '김%‘ 

        MINUS 

        select * from emp b where b.job ='sales'; 

→(2)select * from emp a where a.ename like ‘김%’ and NOT EXISTS( 

        select * from emp b where a.ename=b.ename and b.job='sales'); 

(1)번은 앞에서와 같은 변형방법으로 이것의 검색 횟수는 (자료가 n튜플 이라면) 2n번이 되겠습니다. 그에 비해 (2)번은 둘다 full scan이 일어나서 검색 횟수는 n2이 되겠죠. 

4) NULL, NOT NULL의 경우 

◦select * from emp where ename si not null; 

→select * from emp where ename > ''; 

ename이 문자형일 경우에 사용하는 예입니다.  

◦select * from emp where comm is not null; 

→select * from emp where comm > 0; 

comm이 number형일 경우 사용하는 예입니다. 

◦select * from emp where comm is null; 

→이건 full scan이 필요하겠죠. 아니면 null 값만을 가지고 index를 생성할수도 있으나 그만큼의 null이 있다면 그 외의 경우에서 빼는 방식이 더 빠르겠죠.

많은 사람들이 NULL을 정확하게 이해하지 못하고 사용하기를 꺼려합니다. 물론 그렇지 않은 분들도 많으시겠지만.... ^^;; 일단 하나만 기억 하고 넘어가야 할 것은 NULL이 탐색의 키로 이용될 경우 무조건 full scan이 발생하므로 이용시 많은 주의가 필요합니다. 그럼 NULL대해서 알아보죠. 

NULL은 테이블내에서 공백으로 표시 됩니다. 특징으로는 다음과 같죠 

∘ 어떤 값보다 크지도 않고 작지도 않다. 

∘ 그러므로 어떤 값과 비교될 수 없다. 

∘ 즉, NULL과의 연산결과는 NULL이 된다. 

대부분의 사람들이 세 번째를 놓치게 되는 경우가 많이 있습니다. 

즉 a,b중 하나가 NULL이면 avg(a+b)와 avg(a)+avg(b)는 모두 결과가 NULL이 됩니다. 

그러나 sum(a)의 경우는 NULL값을 참여시키지 않기 때문에 정확한 값이 나오죠. 

 그러면 이러한 NULL을 어떻게 이용 할 것인가? 

일단 조건이 있습니다. 특정한 data type이 테이블 내에서 많은 경우 아울러 full scan이 꼭 필요한 경우 이 data type을 NULL로 지정합니다. NULL은 공백으로 표시 되기 때문에 기억장치에서 공간을 차지 하지 않습니다. 따라서 NULL로 지정한 만큼 공간을 절약할 수 있겠죠. “그게 얼마나 된다고 굳이 NULL로 지정합니까?” 이렇게 물으신다면 만약 테이블 내에서 남여를 구분하는 column이 있다고 가정하면 남과 여중 한 값을 NULL로 한다면 일단 50%는 아끼는 셈이 되죠. 그양이 비록 작을 지라도. 따라서 이 경우에도 손익을 생각하셔서 적용하시면 됩니다. 

또 다음과 같은 경우에 NULL을 사용합니다. 


∘ 미확정 값을 표현하고자 할 때 

∘ 특정 값이 지나치게 많고 나머지 값만 주로 인덱스로 액세스 하고자 할때(위의 경우와 인덱스적용하여 공간과 탐색시간을 줄여주는 방법입니다.) 

∘ 결합인덱스의 구성컬럼이 된다면 NOT NULL로 

∘ 입력 조건값으로 자주 사용되면 NOT NULL로 


마지막의 두가지 경우는 앞으로 나올 예정이므로 따로 설명하지 않겠습니다. 


5) Optimizer의 취사선택으로 index scan이 발생되지 않는 경우를 앞서 살펴 보았습니다. 그러면 어떻게 해야 Optimizer가 제대로 index를 적용하도록 할까요? 이것을 알기위해서 먼저 Optimizer의 역할에 대해서 알아 보겠습니다. 

Optimizer의 목표는 select, update, insert, delete문을 최소한의 프로세싱 시간과 최단 시간의 I/O를 사용하여 실행 시키도록 하는 것이다. 이를 위해 실행계획을 세우고 문장을 실행하기 전에 가장 효과적인 계획을 선택하는 일을 한다. 이를 위해 Optimizer는 실행계획중 규칙기반 접근법(rule-based approach) 또는 비용기반 접근법(cost-based approach)중 하나를 선택한다. 그러나 Optimizer역시 사람이 만든것이라 완벽하게 처리할 수 없다 따라서 만물의 영장인 사람이 정확한 정보를 주어 신속하게 처리하도록 도움을 주어야만 한다. 그럼 앞에서 말한 두가지 접근법에 대해서 알아 보도록 하겠습니다.


①Rule-Based방식 

여러개의 가능한 경로를 찾아서 이미 정해져 있는 Rank를 기준으로 서로의 비용을 비교하고, 이를 토대로 가장 효율적인 것을 선택한다.

옵션 
 액세스경로(Access Path) 
 

 ROWID에 의한 단일 행 접근 
 

 클러스터 조인(Cluster Join)에 의한 단일 행 접근 
 

 Unique key 또는 Primary key를 사용하는 Hash Clushter key에 의한 단일행 접근 
 

 Unique key 또는 Primary key에 의한 단일행 접근 
 

 Cluster Join 
 

 Hash Cluster key 
 

 Indexed Cluster key 
 

 복합키(Composite key) 
 

 단일 컬럼 인덱스(single-column indexes) 
 
10 
 인덱스 컬럼에서의 바운드 범위 조회 
 
11 
 인덱스 컬럼에서의 언바운드 범위 조회 
 
12 
 sort-merge join 
 
13 
 인덱스 컬럼의 MAX 또는 MIN값 
 
14 
 인덱스 컬럼에서의 order by 사용 
 
15 
 full-table scan 
 


②Cost-Based방식 

가장 효율적인 실행계획을 선택하기 위해서 데이커베이스의 통계자료를 사용한다. 오라클 RDBMS사용시 ANALYZE명령어를 사용하면 테이블, 클러스터, 인덱스 등의 통계자료들이 수집, 저장 된다. Cost-Based방식은 이렇게 모인 데이터를 사용한다. 


③ANALYZE명령어 

Cost-Based방식에 사용할 통계 데이터를 모아준다. 또한, 이 명령어는 다음과 같은 목적으로도 사용된다.

Function 
 설   명 
 
통계데이터 수집
 Table, Cluster, Index등에 관련된 자료들을 모아 Cost-Based Optimization에 사용한다. 
 
데이터 무결성 확인
 Table, Cluster, Index등의 무결성 확인 작업을 한다. 
 
Chained-row통계
 Table, Cluster에 있는 데이터 체인행(Chained row)에 대한 통계 자료 수집 
 


그럼 Optimizer가 어떻게 작동하는지 몇가지 예를 들어 보겠습니다. 

∘select * from emp where ename like 'ab%' and empno='7890'; 

→둘다 index일 때 값이 더욱 확실한 empno index만 사용합니다. 

∘select * from emp where ename like 'ab%' and job like 'sa%'; 

→ename or job index중 하나만 사용, 혹은 full scan(이 경우엔 index merge라고 함) 

∘select * from emp where empno > '10'; 

→이와 같은 경우는 특정한 값을 찾는 것이 아니라 테이블 전체를 탐색해야 하므로 full scan선택이 비용이 덜듭니다. 따라서 full scan 선택. 

∘select /* INDEX(emp job_IDX)*/ from emp where ename like 'ab%' and job like 'sa%'; 

→만약 데이터의 분포도나 탐색빈도수가 job index가 월등히 많이 사용된다면 프로그래머가 강제적으로 우선순위를 높여줄수 있는데 이것이 바로 HINT라고 합니다. 형식은 위와 같이 쉽운 편이지만 테이블에 들어가는 데이터들에 대한 지식이 우선되야 하겠지요. 

<Hints에 관하여... 

Hints를 통해서 optimizer에게 알려줄수 있는 정보는 다음과 같습니다. 

-SQL연산을 위한 Cost-based접근 방식의 목표 

-index보다 더 효과적인 Scan방식 

-Join순서 

-병렬연산 순서 

문법 

/*+comment */ →‘+’ 다음에 나오는 내용이 Hints라는 것을 Optimizer에게 알려준다. 

이정도만 이해하고 넘어가도 될 것 같습니다. 


 


 


▸Index의 활용 및 적용기준 

“index를 언제 사용 할 것이냐?” 문제가 되겠지요. 절대적인 기준은 아니지만 대개의 경우 적용할 만한 적용 기준은 다음과 같습니다.


-6블록 이상의 테이블에 적용(6블록 이하는 연결고리만) 

-컬럼의 분포도가 10-15%이내인 경우 적용 

-분포도가 범위내이더라도 절대량이 많은 경우에는 단일 테이블 클러스터링을 컴토할 것 

-분포도가 범위 이상이더라도 부분범위 처리를 목적으로 하는 경우에는 적용 

-인덱스만을 사용하여 요구를 해결하고자 하는 경우는 분포도가 나쁘더라도 적용할 수 있음(손익분기점 10-15%이내) 

-질의에서 선택된 column의 값이 동일한 Rows들은 그 Table에 할당된 data block에 균일하게 분산되어 있을 때 

-Table의 row는 질의되는 column에 대하여 불규칙적으로 분포 

-Table에 할당된 각 data block은 최소한 10개의 row를 포함할 때 적용 

-Table은 상당히 작은 수의 column을 가질 때 

-Table에 대한 대부분의 질의들은 비교적 단순한 WHERE절일 때 

-Cache hit ratio는 낮고 operating system cache는 없을 때


<분포도 = 1/컬럼값의 종류 * 100 = 컬럼값의 평균 로우수/테이블의 총 로우수 * 100 

대개 앞의 것을 많이 이용합니다. 예를 들어 5가지 데이터가 들어있는 컬럼의 분포도는 20%이다.


 


 

<부분범위 처리란? 

먼저 전체범위 처리에 대해서 알아보면 SQL문에서 group by문이나 order by 문의 경우 테이블의 처음부터 끝까지 전제적으로 정렬이 이루어 져야 한다. 이러한 경우를 전제 범위 처리라 한다. 이와는 반대의 경우를 부분범위 처리라하고 튜닝시 되도록 전제범위처리를 피하는 것이 바람직하다. 


 

<손익분기점 read하고자 하는 컬럼스/access해야할 컬럼수 * 100 

 손익분기점이 높으면 hit ratio가 낮음을 의미하고, 손익분기점이 낮으면 hit ratio가 높다. 


 


 


지금까진 single index만을 살펴 보았습니다. 그러면 결합인덱스에 대해서 알아 보겠습니다. 

결합 인덱스는 말그대로 2개이상(오라클에선 16개까지 가능)의 컬럼을 가지고 index를 생성하는 경우를 말합니니다.  

▸결합인덱스의 장점 

-좋은 분포도 : 나쁜 분포도를 가진 column을 결합한 결합 인덱스가 더 좋은 분포도를 가질 수 있다. 

-저장 공간의 효율성 : 한 질의에 의해 선택된 모든 칼럼이 결합인덱스에 있을 경우, table을 access하지 않고 결합 인덱스 만으로 원하는 값을 가져올 수 있다. 그러나 그만큼의 디스크나 메모리에 부하가 많이 걸릴 것이다. 

[예] select empno from emp where empno='123';  

이 경우는 특별히 테이블을 access하지 않고 index만으로 해당값을 출력할수 있다. 따라서 검색속도가 비약적으로 빨라지는 효과를 볼 수 있습니다. 

▸결합 인덱스의 column선택을 위한 지침  

-각 column의 분포도 보다 결합 인덱스에서 결합된 분포도가 더 좋을 경우 

-여러 질의에서 하나이상의 칼럼값을 가진 칼럼의 동일한 집합을 질의할 경우, 이들 모든 칼럼을 포함하는 결합 인덱스 생성을 고려한다. 

▸결합 인덱스 구성시 column순서 배치를 위한 지침  

-WHERE절에 사용된 칼럼을 선행부분으로 만들기 위한 결합 인덱스를 생성 

-칼럼의 일부가 WHERE절에서 자주 사용될 경우 =>자주 select되는 column을 선행부분올 만들어서 이 column만으로 인덱스를 사용할 수 있도록 한다.  

-모든 칼럼이 WHERE절에서 동일하게 사용되면 =>질의 성능을 개선하기 위하여 CREATE INDEX statement에서 분포도가 좋은 순서대로 배열 

-모든 칼럼이 WHERE절에서 동일하게 자주 사용되지만 데이터가 한 column에 대해 물리적으로 정렬되어 있으면 =>그 column을 결합 인덱스의 첫번째로 구성 

-‘=’을 사용할 땐 선택범위가 좁은 것을 앞에 놓는다.


<in을 이용한 access효율 향상. (in은 ‘=’의 의미를 가지고 있다.) 

예) select * from tab1 where col1='a' and col2 between '111' and '112'; 

→select * from tab1 where col1='a' and col2 in('111', '112'); 

여기서 col2의 값이 적을수록 후자의 속도가 빨라진다. 물론 보통의 경우에도 후자가 빠르다. 

일반적으로 between, like문이 들어가는 SQL문은 in문으로 대체해 준다. 


 


 

[주의] 만약 index가 (a+b+c)로 이루어져 있을 경우 where조건에서 a, a+b, a+c, a+b+c가 나오면 index적용이 가능 하지만, b, b+c가 나오면 index적용이 불가능하다. -> B*Tree에서 검색이 불가능 하기 때문에.. 따라서 결합인덱스의 첫 번째 컬럼이 꼭 나와야 index를 적용할 수가 있다. 아울러 대개의 결합인덱스는 최고 5개까지가 적당함. 그럼 간략히 정리를 해보겠습니다. 

<인덱스 선정 절차 

-해당 테이블의 액세스 유형조사 

-대상 컬럼의 선정 및 분포도 분석 

-반복 수행되는 액세스 경로의 해결 

-클러스트링 검토 

-인덱스 컬럼의 조합 및 순서의 결정 

-시험생성 및 테스트 

-수정이 필요한 애플리케이션 조사 및 수정 

-일괄 적용 

<액세스 유형의 조사(설계단계) 

-반복 수행되는 액세스의 형태를 찾는다. 

-분포도가 아주 양호한 컬럼의 찾아 액세스 유형을 찾는다. 

-자주 넓은 범위의 조건이 주여되는 경우를 찾는다. 

-자주 조건절에 사용되는 컬럼들의 액세스 유형을 찾는다. 

-자주 결합되어 사용되는 경우를 찾는다. 

-sort의 유형을 조사한다. 

-통계자료 추출을 위한 액세스 유형을 조사한다. 

<index의 활용(선정기준) 

-분포도가 좋은 컬럼은 단독적으로 생성하여 활용도 향상 

-자주 조합되어 사용되는 경우는 결합인덱스 생성 

-각종 엑세스 경우의 수를 만족할 수 있도록 인덱스간의 역할 분담. 

-가능한 수정이 빈번하지 않는 컬럼 

-기본키 및 외부키(조인의 연결고리가 되는 컬럼) 

-반복수행(loop)되는 조건은 가장 빠른 수행속도를 내게 할 것 

-실제 조사된 액세스 종류를 토대로 선정 및 검증 

<index의 활용(고려사항) 

-새로 추가된 인덱스는 기족 액세스 경로에 영향을 미칠 수 있음 

-지나치게 많은 인덱스는 오버헤드 발생 

-넓은 범위를 인덱스로 처리시 많은 오버헤드 발생 

-Optimizer를 위한 통계데이타를 주기적으로 갱신 

-인덱스의 개수는 테이블의 사용형태에 따라 적절히 생성 

-분포도가 양호한 컬럼도 처리범위에 따라 분포도가 나빠질 수 있음. 

-인덱스 사용원칙을 준수애야 인덱스가 사용됨 

-조인(join)시에 인덱스가 사용여부에 주의 

-데이터 변경시 자주 리빌드해주는 것이 좋다.



Ⅱ. Cluster

 cluster는 테이블에 데이터를 저장하는 방식입니다. 데이터를 저장하는데 있어서 클러스터를 사용할 것인지의 여부는 SQL문장과는 아무런 관계가 없으면, 단지 테이블을 저장하는 방법에 적용됩니다. cluster는 다수 개의 테이블을 하나의 오라클 블록에 저장하는 메커니즘이며, cluster index를 꼭 필요로 합니다. 테이블을 clustering하는 순서는 다음과 같습니다.


①cluster를 생성한다. 

②cluster index를 생성한다. 

③cluster table들을 생성한다. 

그럼 cluster생성 문법을 알아 보겠습니다. 

CREATE CLUSTER cluster( 

        column data_type, ... 

        [PCTUSED int] 

        [PCTFREE int] 

        [INITRANS int] 

        [MAXTRANS int] 

        [SIZE int [K or M]] 

        [TABLESPACE tablespace] 

        [STORAGE storage_clause] 


여기서 주의 해야 할 것은 SIZE로 이것은 하나의 클러스터 키와 그 데이터를 함께 저장하는 데 필요한 스페이스의 크기를 byte단위로 지정한다. 즉 SIZE는 하나의 데이터 블록에 같이 저장될 쉬 있는 클러스터 키의 총수를 결정 짓는 옵션이다. 


[예] 

①create cluster cluster_t1_t2( 

        idnum number(3) 

size 400 

tablespace data1 

storage (initial 30k); 


②create index ind_cluster_t1_t2( 

on cluster cluster_t1_t2 

tablespace idx1; 


③create table t1( 

name varchar2(10), 

hire_date date, 

idnum number(3) 

cluster cluster_t1_t2 (idnum); 

create table t2( 

name varchar2(10), 

idnum number(3) 

cluster cluster_t1_t2 (idnum); 


이렇게 지정하면 테이블 t1과 t2의 데이터는 같은 데이터 블록에 저장됩니다. 그럼 이제 본론으로 들어가겠습니다. 

이해를 쉽게하기 위해 앞에서 보았던 index와 cluster index의 차이 점을 짚어보면 일반 index는 rowid를 가지고 있는 반면 cluster index는 block의 header를 가지고 있습니다. 따라서 보통의 경우엔 일반 index가 빠른 속도를 냅니다. 그러나 중복 데이터를 많이 가지고 있는 컬럼이 있는 테이블의 경우 그 성능이 훨씬 높게 됩니다. 물론 I/O이용이 적으면서 이러한 효과를 볼 수 있다니 얼마나 좋습니까. 따라서 앞에서 다루었던 index와 마찬가지로 cluster 역시 해당 테이블에 대한 정확한 이해를 바탕으로 이루어 져야 합니다. 그럼 정리해 보겠습니다. 

<cluster의 특징 

-지정된 컬럼값의 순서대로 로우를 저장시키는 방법 

-하나 혹은 그 이상의 테이블을 같은 클러스터내 저장 가능 

-엑세스 기법이 아니라 액세스 효율향상을 위한 물리적 저장기법 

-검색 효율을 높여주나 입력, 수정, 삭제시는 부하증가 

-분포도가 넓을 수록 오히려 유리(인덱스의 단점을 해결 5~7배) 

-분포도가 넓은 테이블의 클러스터링은 오히려 저장공간 절약 

마지막 것은 좀 이해가 안되는 부분이요. 이유인 즉슨 오라클 내부에서 동한건에 대해 나머지 값들은 저장이 안된다고 합니다. 따라서 그만큼의 저장 공간이 절약되겠죠. 

<cluster의 활용(선정기준) 

-6블록 이상의 테이블 

-다량의 범위를 자주 액세스 해야 하는 경우 

-인덱스를 사용한 처리가 부담되는 넓은 분포도 

-여러 개의 테이블이 빈번한 조인을 일으킬 때 

-반복 컬럼이 정규화 작업에 의한 어떨수 없이 분할된 경우 

-UNION, DISTICT. ORDER BY, GROUP BY가 빈번한 컬럼이면 고려해 볼 것 

-수정이 자주 발생하지 않는 커럼

-처리 범위가 넓어 문제가 발생되는 경우 단일 테이블 클러스터링 

-조인이 많아 문제가 발생되는 경우는 다중 테이블 클러스터링 

<cluster의 활용(고려사항) 

-데이터 처리(입력, 수정, 삭제)에 오버헤드 발생 주의 

-인덱스로도 충분한 범위는 클러스터링 효과가 없음 

-클러스터 키는 수정이 빈번하지 않을 것 

-각종 액세스형태에 대해 인덱스와 적절한 역할 분담 

-클러스터링은 기존의 인덱스의 수를 감소시킴(인덱스 재구성) 

-클러스터 SIZE 인자가 중요 

-클러스터 키별 로우 수의 편차가 심하지 않을 것 

-클러스터에 데이터 입력시 로우가 적은 테이블부터 실시할 것 

-클러스터링된 테이블 조인시 로우 수의 역순으로 from절에 기술할 것 

-클러스터 키를 첫 번째로 하는 인덱스는 생성하지 말것(optimizer에 의해 선택 문제 발생) 

<index와 cluster의 비교





 


Ⅲ. VIEW 

 보통 뷰를 이용는 경우는 보안이나 복잡한 쿼리를 피하기 위해 사용 하는 경우가 많이 있습니다. 그럼 과연 튜닝에는 어떻게 쓰일수 있을까요? 일반적으로 튜닝시에는 다음의 두가지 목적을 위해 사용합니다. 


<수행속도 향상을 위한 뷰 

-수행 속도 향상을 위해 미리 튜닝한 select문을 뷰로변환 시켜 사용 

-M:1조인의 연결회수를 감소 시키기 위해 먼저 group by된 뷰를 만들고 그 뷰와 조인을 일으키게 하기 위한 뷰 

-특정 client tool의 문제 해결을 위한 뷰 

-수행 속도에 심한 영향을 주는 넓은 범위 처리나 특정 컬럼의 조건검색을 막아 악성검색을 방지하기 위한 뷰 

-특정한 절차로 수행시키기 위해 뷰의 select list에 suppressing, hint등을 사용한 뷰 

설명이 필요 없으리라 생각됩니다. 

<SQL 기능 향상을 위한 뷰 

-불규칙적인 sort가 필요한 경우 

-group by결과를 다시 가공하고자 하는 경우(group by는 어쩔수 없이 full scan이 발생 합니다. 따라서 그에따른 비용도 많이 듭니다. 따라서 미리 group by결과를 뷰로 가지고 있으면 그만큼의 비용을 절감 할 수 있겠지요) 

-서로 다른 테이블의 group by결과를 같은 줄에 맞추려는 경우 

-ROWNUM을 이용한 특별한 처리 

-각 row에 있는 값들(예:일자)간의 가공처리(예:기간산정) 

-각각의 소계와 그 내역을 하나의 SQL로 처리 

-복잡한 outer join의 해결을 위한 뷰(outer join은 만족하는 레코드뿐만 아니라 만족하지 않는 레코드들도 출력을 해줍니다. 따라서 만족하지 않는 값으로 찾고자 할 경우 full scan이 발생하여 전제 SQL문의 속도를 늦춰 줍니다. 이러한 경우 뷰를 이용하여 만족하지 않는 레코드를 따로 처리해 놓으면 훨씬 빠른 속도를 얻을수 있습니다.) 

-테이블은 row를 가지지 않으나 뷰는 row를 가지도록 한 뷰 

-SQL*From의 execute_query를 활용하기 위한 뷰 

-기타 SQL의 기능 확장을 위해 원하는 임의의 집합이 필요한 경우 

-코드성 테이블을 미리 조인한 후 fact table과 다시 조인한다.(코드성테이블이란 master file과 같은 의미로 삽입이나 삭제가 거의 되지 않고 참조위주의 테이블을 말합니다. 예로 이자율테이블이나 할인율 테이블 같은 것이 되겠죠, 그리고 fact table은 사용자가 입력한 테이터 정보를 모두 가지고 있는 테이블입니다. 보통의 테이블들이 해당 되겠죠. 아울러 덩치도 아주 큽니다.) 

-조인시 데이터 범위가 작은 테이블을 먼저 조인한 다음 점점 큰 순서로 조인하는 것이 훨씬 빠른 속도를 냅니다. 

Ⅳ. 부분범위 처리(Partial Range Scan) 

그럼 일단 그림을 먼저 보겠습니다





 

<부분범위 처리 방법 

-조건을 만족하느 전제 집합이 아닌 일부분만 access 

-data량이 많아도 performance에 지장이 없고, 오히려 향상 

-index나 cluster를 적절히 활용한 sort의 대체(order by사용을 대체) 

-max처리 

-table은 access하지 않고 index만 사용하도록 유도 

-exists의 활용 

-rownum의 활용 (rownum- 1,2차 가공시 나오는 건수) 

-query를 이원화 하여 일부분씩 scan하도록 유도 

-stored function을 이용 

[예] 

여기서 첫 번째 문장에서는 index가 ymd만으로 이루어졌고, 두 번재 문장에서는 index가 ymd+item으로 이루어 졌다고 가정합니다. 

∘select * from product where ymd='951023' and item like 'ab%' order by ymd, item; 

→select * from product where ymd='951023' and item like 'ab%'; 

sort를대체하는 예 

∘select orddate, custno from orddate between '940101' and '941130' order by orddate desc; 

→select --+index_desc(a orddate) orddate, custno from order1t a where orddate between '940101' and '941130'; 

∘select orddate, custno from order1t where orddept like '7%' order by orddate desc; 

→select --+index_desc(a orddate) orddate, custno from order1t a where orddept like '7%' and orddate <='991231';


<index생성시 아무 옵션도 주지않을 경우 default로 ASC옵션이 적용되어 생성된다. 

따라서 DESC로 출력을 원할 경우 다음 두방법중 하나를 이용하면 된다. 

1. 뒤에서부터 검색하거나 

2. index create시 desc로 생성시켜줘야 속도 향상을 얻을 수 있다. 


 


 

max처리하는 예 (전자는 index(dept), 후자는 index(dept+seq)로 index생성 되어 있음) 

∘select max(seq)+1 from product where dept='12300'; 

→select /*+index_desc(a index1)*/ seq+1 from product a where dept='12300' and rownum=1; 


rownum이용 예 

∘select count(*) into:cnt from item_tab where dept='101' and seq>100 ...... 

→select 1 into:cnt from item_tabl where dept='101' and seq>100 and rownum=1... 

1:M join의 부분범위 유도 예 

∘select x.cust_no, x.addr, x.name, ....... from cust x, reqt y where x.cust_no=y.cust_no and x.cust_stat in ('a', 'c', 'f') and y.un_pay >0 group by x.cust_no having sum(y.un_pay) between :val1 and :val2; 

→select cust_no, addr, un_pay, .... from (select cust_no, addr, unpay_sum(cust_no) as un_pay, ......... from cust where cust_stat in ('a', 'c', 'f')) where un_pay between :val1 and :val2;



Ⅴ. 조인 메커니즘의 이해 

조인의 경우 사용히 매우 신중을 기해야 하는 것중의 하나입니다. 특히 조인 컬럼이용되는 컬럼의 선정시 특히 많은 주위를 해야 optimizer의 실행 순서 선택시 우리가 원하는 수행능력을 보장 받을 수 있습니다. 그럼 조인시 수행속도에 영향을 끼치는 것들에 대해서 한가지씩 알아 보겠습니다.


<driving의 영향





<Join순서의 영향





 

<index의 영향 

양쪽에 index 
 한쪽에 index 
 
① 
 tab1 
 range scan 
 ③ 
 tab1 
 range scan 
 
tab2 
 index scan 
 tab2 
 full scan 
 
② 
 tab1 
 range scan 
 ④ 
 tab1 
 full scan 
 
tab2 
 index scan 
 tab2 
 range scan 
 


①,②의 경우는 일량의 변화가 없다. 

③의 경우 n*m번 비교가 일어난다.(최악의 경우) 이런 경우 ④과 같이 변형하면 조금이나마 성능 향상에 도움이 된다. 

<Join시 유의사항 

-join되는 key column의 data type을갖게 한다. 

-join되는 key column을 index로 만들어 준다.(절대 변형되지 않도록한다.-변형시 full scan발생) 

-두 table간에 join이 맞지 않을 경우(한쪽에만 index가 있는 경우) driving table을 full scan table로 설정하는 것이 최악의 경우를 방지 할 수 있다. 

-두 index에 대한 분포도가 같은 경우 from절의 오른쪽에 있는 table을 driving으로 삼는다. 

-check조건이 되는 테이블의 범위는 넓을 수록 좋다.(사용자에게 테이블의 내용을 빨리 display 할 때 보다 빨리 전송단위 씩 보내줄수 있기 때문에) 

<join과 loop query의 속도 비교. 

-loop query가 빠른 경우 → 부분범위 처리가 발생 할 경우 

-부분범위 처리가 join과 loop query 둘다 발생하면 (전체가 부분범위 처리인 경우) → join이 빠르다. 

-전체 범위 처리가 발생한 이유가 모든 table에 있으면 → join이 빠르다. 

-연결되는 table중 하나를 부분범위로 바꿀수 있다면 → loop query가 빠르다. 

<Loop query? 

말 그대로 query를 loop로 돌려 특정 값을 다음 테이블내에서 찾는 방법입니다. 보통의 SQL문에서 사용하는 경우는 거의 없고 batch 혹은 pl_SQL 사용시 많이 이용됩니다. 


 



Ⅵ. Trace 

하하 이젠 분석도구라 불리는 놈들을 보겠습니다. 어디가 잘못 됐는지 알아야 고칠거 아닙니까? 따라서 가장 중요하다고 생각합니다. 그런데 어렵더군요. 저 역시 교육 받을 때 이 부분에서 거의 헤맸습니다. ^^;; 여러분은 그러시지 않기를 빕니다.  

<SQL Trace? 

SQL문을 튜닝하기 위해서는 현제의 SQL문이 어떻게 수행되는 가를 정확하게 파악해야 할 필요가 있습니다. 그럼 간단하게 Trace의 사용 목적에 대해서 알아보죠. 

< Trace 파일은 시스템을 튜닝하는데 필요한 아주 유요한 정보(cpu Time, 총수행시간, I/O횟수 등등 아래 자세히 설명)를 제공한다.  

< SQL문의 실행통계를 Session별로 모아서 Trace 파일을 만든다. 

   - SQL Parsing, Execute, Fetch를 수행한 횟수 

   - CPU Time, Elapsed Time(총 경과시간) 

   - Disk(물리적), Memory(논리적) I/O 수행한 횟수 

   - 추출된 Row의 수 

   - 라이브러리 캐쉬 miss 수 

   - Parse Count 

그럼 trace를 한번 만들어 보자구요. 물론 슆지는 않습니다. 또한 Trace를 생성하는 동안 시스템 전체적인 수행성능은 20%~30% 정도 감소합니다. 따라서 운영중인 DB의 경우에는 되도록 사용을 금하기소 되도록 개발용 장비에서 실행하기기 바랍니다. 

먼저 SQL_TRACE를 생성하려면 다음과 같은 파라미터들을 INIT.ORA에 지정해야합니다. 

- CREATE INDEX문에서 NOSORT Option의 사용 

- TIMED_STATISTICS=TRUE → 시간 통계를 모을 수 있게 한다. 

- SQL_TRACE=TRUE → Session을 종료하는 모든 사용자들의 Trace를 수행한다. 

- USER_DUMP_DEST=directory path → SQL_TRACE가 Trace 파일을 저장하는 디렉토리를 지정한다. default는 시스템 덤프(dump) 디레토리이다.(예; oracle_home/rdbms/log) 

-MAX_DUMP_SIZE=number → Trace 파일의 물리적인 크기를 바이트 단위로 지정할 수 있게 한다. 

[주의] SQL_TRACE는 공간이 부족하면, 완전한 출력이 되지 않습니다. 따라서 디스크 공간을 확보하신후 실행 시키싶시오, 아울러 주기적으로 필요 없는 파일들은 삭제해 주어야 합니다. 

[예]  

timed_statistics = true          # if you want timed statistics 

user_dump_dest = /oracle8/app/oracle/product/8.0.3/rdbms/log 

max_dump_file_size = 10240       # limit trace file size to 5 Meg each 

-SQL*Plus에서는 다음과 같이 세션을 초기화시켜야 합니다. 

SQL>alter session set sql_trace=true; 

-optimizer goal의 변경은 다음과 같습니다. 

SQL>alter session set optimizer_goal=rule;(optimizer goal을 정의) 

-RDBMS_SYSTEM.SET_SQL_TRACE_IN_SESSION Produce사용 

SQL>execute RDBMS_SYSTEM.SET_SQL_TRACE_IN_SESSION(11,6,TRUE) 

여기서 11은 sid, 6은 Serial number(둘다 v$session에서 확인), TRUE는 Trace enable입니다. 

이렇게 설정해 두면 실행되는 질의문에 대해서 트레이스 파일이 생성된다. 생성되는 위치는 initSID.ora에서 정의한 user_dump_dest 디렉토리에 *.trc형태로 생성됩니다. 

그럼 이제 Trace 파일을 보기만 하면 됩니다. 그러나 생성된 트레이스 파일은(*.trc) 바로 볼 수 없습니다. 시험삼아 한번 vi에디터로 열고 보셔도 물론 됩니다. 그러나 수많은 문자들 가운데서 우리가 원하는 정보를 찾기란 너무 어렵습니다. 그래서 tkprof라는 유틸리티를 사용하여 생성된 트레이스 파일을 분석이 가능한 형식으로 전환해줘야 합니다. 물론 기본적으로 오라클에서 제공하는 유틸리티입니다.

이것은 이미 생성된 트레이스 파일이나 트레이스 파일을 생성하고 있는 중에도 tkprof를 수행시킬 수 있습니다. 트레이스 파일은 SQL문에 대한 실행계획뿐만 아니라 실행시간, 다양한 옵션을 이용하여 분석하기 쉬운 형태 등의 정보를 보여줍니다.

그럼 tkprof란 놈은 어떻게 실행 시킬까요? 

Usage: tkprof tracefile outputfile [explain=user/passwd] [table=schema.tablename] 

            [print=integer] [insert=filename] [sys=yes/no] [sort=option] 

 tracefile : 생성된 트레이스 파일명 

 outputfile : tkprof가 출력하는 텍스트 파일명(디폴트로 확장자가 .prf임) 

 explain=user/passwd : 해당 트레이스 파일이 수행된 세션의 사용자 및 패스워드 

 table=schema.tablename : 실행계획(execution plan)을 저장할 TKPROF 임시 테이블의 이름 

 print=integer : 트레이스 파일별로 출력시킬 SQL문의 수 

 aggregate=yes|no 

 insert=filename : List SQL statements and data inside INSERT statements. 

 sys=yes/no : TKPROF does not list SQL statements run as user SYS. 

 record=filename : Record non-recursive statements found in the trace file. 

 sort=option : Set of zero or more of the following sort options: 

 < sort option의 종류 > 

    prscnt number of times parse was called 

    prscpu cpu time parsing 

    prsela elapsed time parsing 

    prsdsk number of disk reads during parse 

    prsqry number of buffers for consistent read during parse 

    prscu  number of buffers for current read during parse 

    prsmis number of misses in library cache during parse 

    execnt number of execute was called 

    execpu cpu time spent executing 

    exeela elapsed time executing 

    exedsk number of disk reads during execute 

    exeqry number of buffers for consistent read during execute 

    execu  number of buffers for current read during execute 

    exerow number of rows processed during execute 

    exemis number of library cache misses during execute 

    fchcnt number of times fetch was called 

    fchcpu cpu time spent fetching 

    fchela elapsed time fetching 

    fchdsk number of disk reads during fetch 

    fchqry number of buffers for consistent read during fetch 

    fchcu  number of buffers for current read during fetch 

    fchrow number of rows fetched 

    userid userid of user that parsed the cursor 

여기서 SQL문을 실행하는데 걸린 CPU시간을 보여주는 EXECPU가 가장 실용적이다. 만약 init.ora 파라미터를 TIMED_STATISTICS=FALSE로 지정했을 때는 수행 중에 액세스된 블록 수를 보여주는 EXEQRY가 가장 실용적이다. 

[예] tkprof ccdb_ora_1124.trc 1124.txt explain=scott/tiger 

그럼 이제 우리가 눈으로 보기에 꽤 괜찮은 파일이 만들어 집니다.  

- tkprof는 정형화된 리스트(출력파일)를 생성합니다..

- 생성된 파일에는 다음과 같은 내용들을 포함하고 있습니다.

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

보기 좋게 표로 만들었습니다만 실제론 이렇게 출력되진 않습니다. 그럼 하나 하나 살펴 보지요. 

- parse 

·SQL문이 파싱되는 단계에 대한 통계이다. 새로 파싱을 했거나, 공유 풀에서 찾아 온 것도 포함된다. 

·단, PL/SQL 내에서 반복 수행(Loop)된 SQL이나 PRO*SQL에서 보존커서(Hold cursor)를 지정한 경우에는 한번만 파싱된다. 

- execute 

·SQL문의 실행 단계에 대한 통계이다. UPDATE, INSERT, DELETE 문들은 여기에 수행한 결과가 나타난다. 

· 전체범위 방식으로 처리된 결과가 여러 건인 경우는 주로 여기에 많은 값이 나타나며 fetch에는 아주 적은 값이 나타난다. 

- fetch 

·SQL문이 실해되면서 페치된 통계이다.  

· 부분범위 방식으로 처리된 SELECT문들이나 전체범위 처리를 한 후 한 건을 추출하는 경우(AGGREGATE, 전체집계, Count 등)는 주로 여기에 많은 값들이 나타나고 execute에는 아주 적은 값이 나타난다. 

- count 

·SQL문이 파싱된 횟수, 실행된 횟수, 페치가 수행된 횟수이다.  

- cpu 

·pares, execute, fetch가 실제로 사용한 CPU 시간이다.(1/100초 단위)  

- elapsed 

·작업의 시작에서 종료시까지 실제 소요된 총 시간이다.  

- disk 

·디스크에서 읽혀진 데이타 블록의 수  

- query 

·메모리 내에서 변경되지 않은 블록을 읽거나 다른 세션에 의해 변경 되었으나 아직 Commit되지 않아 복사해 둔 스냅샷 블록을 읽은 블록의 수이다.  

·SELECT문에서는 거의가 여기에 해당하며 UPDATE, DELETE, INSERT 시에는 소량만 발생한다.  

- current 

·현 세션에서 작업한 내용을 Commit하지 않아 오로지 자신에게만 유효한 블록(Dirty Block)을 액섹스한 블록 수이다. 

· 주로 UPDATE, INSERT, DELETE 작업시 많이 발생한다. SELECT 문에서는 거의 없으나 아주 적은 양인 경우가 대부분이다. 

- rows 

·SQL문을 수행한 결과에 의해 최종적으로 액세스된 로우의 수이다. 

·서브쿼리에 의해서 추출된 로우는 제외된다. 

·만약 SUM, AVG, MAX, MIN, COUNT 등의 그룹함수를 사용한 경우라면 큰 의미가 없다. 


☞분석결과의 예  

- execute, fetch의 횟수가 동일하다는 것은 SQL 수행시마다 기본키에 의해 한건씩만 처리되고 있다는 것을 의미한다. 만약 pares가 1인데 execurte와 fetch가 100이라면 루프가 100번 수행되면서(어프리케인션은 한번만 수행되고 SQL은 루프 내에서 반복수행되었다. 왜냐하면, 어플리케이션이 여러번 실행되었다면 비록 SQL이 실제 파싱하지 않고 Shared SQL Area에서 찾아 왔다고 해도 parse의 횟수는 증가되기 때문이다) 보관커서 상태의 SQL이 한 건씩을 추출한 상태이다. 이 경우의 SQL문은 'SELECT ... INTO ...'형식으로 사용되었을 것이다.  

- parse가 1이고 execute가 1이며, fetch가 100이라면 SQL은 단 한번 수행되었고(루프 내에서 수행되지 않았음) 페치만 연속해서 100번을 수행한 것이다. 이 경우의 SQL문은 대개 'DECLARE CURSOR'로 선언한 SQL이 'FETCH ... INTO ...'에 의해 SQLCODE가 '1403'(Date Not Found)일 때까지 수행되었거나 부분범위 처리에 의해 일정 양만큼만 수행하고 멈추었을 때이다. 

- parse : execute : fetch의 비율은 공통 작업이 여러번 수행되면 그 배수로 나타난다. 예를 들면 parse : execute : fetch가 10 : 10 : 1000인 경우는 1 : 1 : 100인 작업이 10번 수행되었다는 것을 의미한다. 

- fetch가 10인데 rows가 100이라면 운반단위가 10인 다중처리(Array Processing)를 사용하여 한번 페치마다 10건의 로우가 추출되었음을 의미한다. 

- 트레이스의 중간부분에 'Misses im library cache during parse : 1'이라는 문장이 있다. 이것은 공유 SQL 영역에서 파상된 결과를 찾지 못하여 실제 파싱작업을 하게 되었다는 것을 의미한다. 

- 최종적으로 추출된 로우의 수는 적으나 많은 CPU 시간이 소요되었다면 이것은 분명히 적절한 액세스 경로로 수해되지 않았음을 의미한다. 

- CPU 시간과 ELAPSED 시간의 차이는 적을수록 좋다. 만약 CPU시간에 비해 ELAPSED 시간이 훨씬 많다면, 그 원인은 다음 중 하나일 가능성이 높다. 즉 주변의 다른 세션에서 많은 부하를 발생시켜 시스템 전체에 부하가 많이 걸려있는 경우나 혹은 어플리케이션의 문제이거나 다량의 데이타 처리에 따른 I/O 병목현상이 발생한 경우 

- disk, query, current의 숫자는 적을수록 좋다. 이 숫자들이 커다는 것은 메모리 공유영역의 적중률(Hit Ratio)이 낮다는 것을 의미한다. 

- Overall totals For All Statements에서 적중률 계산은 다음과 같다. 

 (Execute 'disk' + Fetch 'Disk')/(Execute 'query' + Execute 'current' + Fetch 'query' + Fetch 'Current') * 100 

 이 값이 10%이상이라면 메모리 캐쉬에서 데이타를 찾는 비율(적중률)이 너무 낮은 것이다. 

- 다음은 아주 빠른 응답이 요구되는 온라인 프로세싱 시스템의 경우에서만 적용되는 규칙들이다. 

 모든 Execute 'CPU'가 1초보다 적어야 한다. 

 Parse 'CPU' 시간이 Parse당 0.01초보다 적어야 한다. 

 작은 테이블(200로우 이하)에서만 전체 테이블 스캔이 일어나게 한다. 

 sysdate만 찾아오거나, 오직 연산만 하거나, 'SELECT ... INTO ...'로 값을 복사하는 경우를 위해서 DUAL 테이블들을 불필요하게 사용하는 것은 모두 없앤다. 

 동시에 작업되는 SQL들은 가능한 PL/SQL을 사용한다. 

 조인시에 옵티마이져가 적절한 드라이빙 테이블을 선택하는지를 확인하거나, 여러개의 조건들 중에서 주(드라이빙)가 되는 조건들과 부(체크)가 되는 조건들을 확인한다. 또한 적적한 인덱스가 사용될 수 있는지를 확인하여 주조건의 처리범위가 넓지 않도록 항상 유의한다. 



Ⅶ. Analyze 

이 명령어는 Cost-Based방식에 사용할 통계 데이터를 모아 줍니다.

Function 
 설   명 
 
통계데이터 수집 
 table, Cluster, index 등에 관련된 자료들을 모아 Cost-Based Optimizer에 사용한다. 
 
데이터 무결성확인 
 table, cluster, index등의 무결성 작업을 한다. 
 
Chained-row통계 
 table, cluster에 있는 데이터 체인행(Chained row)에 대한 통계 자료 수집 
 


다음으로 문법을 보죠. 문법은 아래와 같습니다.

ANALYZE object-name operation STATISTICS 

-object → TABLE, INDEX, CLUSTER 중에서 해당되는 오브젝트 종류 

-name → 오브젝트의 이름 

-operation  

· COMPUTE : 각각의 값들을 정확하게 계산 따라서 옵션은 가장 정확한 통계를 얻을 수가 있지만 가장 처리속도가 느린 단점이 있습니다. 

·ESTIMATE : 자료사전의 값과 데이타 견본을 갖고 검사해서 통계를 예상 이 방법은 덜 정확한 정보를 주지만 훨씬 처리속도가 빠릅니다. 

·DELETE : 테이블의 모든 통계정보를 삭제


Analyyze와 관련된 데이터 사전 뷰를 정리 했습니다. 

USER_INDEXS, ALL_INDEXS, DBA_INDEXS 

USER_TABLES, ALL_TABLES, DBA_TABLES 

USER_TAB_COLUMNS, ALL_TAB_COLUMNS, DBA_TAB_COLUMNS 





출처 : http://skyforce.egloos.com/1844944

Posted by 1010
02.Oracle/DataBase2010. 6. 16. 10:30
반응형
아주아주 어려운 난관에 부딪쳤다!
쿼리문을 만드는데 세로열로 된 컬럼값을 가로열로 모두 만들어야 한다는 아주 슬픈...
그래서 어떻게 하나... 부족한 실력 자책하며 이곳저곳을 떠돌고 열심히 구글링도 해보고
그래도 답이 없더라. 이런걸 보고 묵묵부답이라는 말을 사용하기도 하지...
하지만 의지의 한국인이라 하지 않던가... ㅋㅋ

여러가지 방안을 모두 사용해봤고 오라클 9i이상에서만 제공된다는 SYS_CONNECT_BY_PATH 도 써 봤고...
그래도 답이 나오지 않았으나 태권브이가 날 살렸다.
아래는 블로그의 내용을 살짝 카피해 온것이다....
글을 올리신 당사자께는 죄송^^

select  gbn,
          substr(xmlagg(xmlelement(a,',' || val) order by val).extract('//text()'), 2) val
  from test
group by gbn  
http://blog.naver.com/hyelee96/140073401311
Posted by 1010
02.Oracle/DataBase2010. 4. 19. 14:43
반응형
[오라클] like 연산에서 %, _ 문자로 검색하기
like 연산시 %는 모든 문자열을, _는 단일 문자를 나타냅니다.
%와 _가 포함되는 데이타를 조회하려면 escape문자를 지정해주면 됩니다.

select * from 테이블 where 컬럼 like '%KIMONG/_%' escape '/';

위와 같이 하면 컬럼에 KIMONG_가 포함되는 모든 열을 반환합니다.
Posted by 1010
02.Oracle/DataBase2010. 4. 5. 15:05
반응형
SELECT *
FROM A
AS OF TIMESTAMP(SYSTIMESTAMP - INTERVAL '15' MINUTE);
Posted by 1010
02.Oracle/DataBase2009. 12. 9. 11:34
반응형
오라클 데이타딕셔너리

All_all_tables : user가 access할수있는 모든 Table
All_catalog : user가 access할수있는 모든 Table, Views, synonyms, sequence
All_clusters : user가 access할수있는 모든 clusters
less..
All_col_comments : user가 access할수있는 모든 Table,Views에 대한 칼럼comments
All_col_privs : user에게 또는 Public에게 허용된 모든 칼럼에 대한 권한.
All_col_privs_made : user가 부여한 칼럼에 대한 권한.
All_col_privs_recd : user에게 또는 Public에게 허용된 모든 칼럼에 대한 권한.
All_coll_types : user가 access 할수 있는 모든 collection type
All_cons_columns : 제약조건에 관련된 칼럼, access할수 있는 대한 정보
All_constraints : access할수 있는 테이블에 대한 제약조건.
All_db_links : user가 access 할수 있는 데이터베이스 link
All_def_audit_opts : 오브젝트가 생성될때 적용될수있는 default오브젝트감사내용.
All_dependencies : user가 access할수있는 오브젝트간의 dependencies(참조,link)
All_directories : user가 access할 수 있는 모든 directories (owner 는 항상 sys)
All_errors : user가 access할수있는 모든 objects(view,procedure,package, function,
packagebody) 에 대한 에러.
All_ind_columns : user가 access할수있는 테이블에 대한 인덱스의 칼럼.
All_ind_partitions : user가 access할수있는 인덱스partition, partition에 대한
storage매개변수, Analyze명령에 의해 결정된 partition통계.
All_indexes : user가 access할수있는 테이블의 인덱스.
이 view의 통계를 수집하기위해, Analyze명령을 사용한다.
병렬partition인텍스탐색을 지원한다.
All_labels : system labels 에 대한 Oracle server view.
All_libraries : user가 access할 수 있는 모든 libraries.
All_lobs : user가 access할 수 있는 모든테이블에 포함된 LOBs.
All_method_params : user가 access할 수 있는 method와 그method의 parameter.
All_method_results :
All_nested_tables : user가 access할수있는테이블내의 Nested Table
All_object_tables : user가 access할수있는테이블의모든정보.
All_objects : user가 access할수있는objects(index partition,table partition,package,
package body, trigger)
All_part_col_statistics : user가 access할 수 있는 테이블partition에 대한 칼럼통계와
막대그래프화된 정보.
All_part_histograms : user가 access할수있는 테이블partition의 histograms에 대한
histogram정보.
All_part_indexes : user가 access할수있는 모든partition된 index의 partition정보.
All_part_key_columns :user가 access할수있는 partition된 objects의 partition key
칼럼에 대한정보
All_part_tables : user가 access할수있는partition된 Table에 대한 partition정보.
All_refresh : user가 access할수있는모든 refresh groups.
All_refresh_children : user가 access할 수 있는 refresh groups 안의 모든objects
All_refs : user가 access할 수 있는 칼럼중 REF칼럼과, REF속성.
All_registered_snapshots : 모든 등록된 snapshots.
All_sequences : user가 access할수있는 sequences.
All_snapshot_logs : 모든 snapshot logs.
All_snapshot_refresh_times : 모든 snapshot refresh times.
All_snapshots : user가 acces할수있는 모든 snapshots.
All_source : user가 access할수있는 모든 stored objects의 text source.
All_synonyms : user가 access할수있는 모든 synonyms.
All_tab_col_statistics : 'User_tab_columns' view안의 정보에대한 칼럼통계와 그래프정보
All_tab_columns : user가 access할수있는모든 table, views, clusters에 대한 칼럼.
이view를 활용하기위해서는 Analyze명령어를 사용한다.
All_tab_comments : user가 access할 수 있는 모든 table, views에 대한 comments.
All_tab_histograms : user가 access할수있는table, views에 대한 histograms.
All_tab_partitions : user가 access할수 있는 각각의 테이블partition에 대한
partition정보, storage parameter, Analyze명령에 의한

통계정보등을 서술한다.
All_tab_privs : user혹은 PUBLIC가 부여받은 오브젝트권한.
All_tab_privs_made : user가 부여한 user권한과 오브젝트권한.
All_tab_privs_recd : user 또는 PUBLIC이 부여받은 오브젝트권한.
All_tables : user가 access할 수 있는 모든 테이블.
Analyze명령으로 이 view의 통계를 얻을 수 있다.
All_triggers : user소유의 trigger, user소유테이블의 trigger, 또는 user가
CREATE ANY TRIGGER 권한을 갖고있다면, 모든 트리거에 대한 정보.
All_trigger_cols : user소유의 trigger, user소유테이블의 trigger, 또는 user가
CREATE ANY TRIGGER 권한을 갖고있다면, 모든 트리거에 대한 칼럼정보.
All_type_attrs : user가 access할 수 있는 type의 attributes.
All_type_methods : user가 access할수있는type의 methods.
All_types : user가 access할 수 있는 type.
All_updatable_columns : join view에서 update가능한 칼럼에 대한 정보.
All_users : 데이터베이스의 모든 user에 대한 정보.
All_views : user가 access할수있는view의 텍스트.
Audit_actions : 감사추적type코드 정보.
catalog : Oracle 5.0 version과의 호환정보를 포함한다.
이view의 사용은 추천할만하지 못하다.
cat : user_catalog 에 대한 synonym.
chained_rows : ANALYZE LIST CHAINED ROWS 명령에 대한 default table.
clu : user_clusters 테이블의 synonym.
code_pieces : dba_object_size 와 user_object_size view를 create 시에 사용됨.
code_size : dba_object_size 와 user_object_size view를 create 시에 사용됨.
col : Oracle 5.0version 호환정보를 포함하고 있다.
cols : user_tab_columns view 의 synonym.
column_privileges : user가 부여한권한,부여받은권한, owner인권한,
또는 PUBLIC에게 부여받은 권한에 대한 칼럼정보.
Dba_2pc_neighbors : 진행중인 트랜잭션에 대한 연결 및 종료에 대한 정보.
Dba_2pc_pending : recovery를 기다리는 분산된트랜잭션에 대한 정보.
Dba_all_tables : 데이터베이스내의 모든테이블(object table, relational table).
Dba_audit_exists : "AUDIT NOT EXISTS" and "AUDIT EXISTS"에 의해 생성된
감사추적요소.
Dba_audit_object : 시스템내의 모든 object에 대한 감사추적기록.
Dba_audit_session : 세션연결과 종료에 관련된 모든 감사 추적기록.
Dba_audit_statement : GRANT, REVOKE, AUDIT, NOAUDIT, ALTER SYSTEM
관련된 감사추적기록.
Dba_audit_trail : 모든 감사추적요소.
Dba_blockers : 누군가가 스스로 걸지않은 lock이 해제되기를 기다리는 session정보.
Dba_catalog : 모든 데이터베이스 table, views, synonyms 과 sequence에 대한 정보.
Dba_clu_columns : cluster칼럼과 table칼럼의 mapping정보.
Dba_clusters : 데이터베이스내에 있는 모든 cluster.
Dba_col_comments : 데이터베이스내의 모든 table, views의 칼럼에대한 comments.
Dba_col_privs : 데이터베이스내의 칼럼에 대한 모든권한.
Dba_coll_types : 데이터베이스내의 모든 collection type, VARRAYs, nested tables,
object tables 등에 대한 정보.
Dba_constraints : 모든테이블에 대한 constraint(primary, check, unique,
referential integrity, with check option on a view,

with read only on a view) 정보.
Dba_cons_columns : constraint 정의안에 있는 access가능한 칼럼에 대한 정보.
Dba_data_files : 데이터베이스파일에 관한 정보.
Dba_db_links : 데이터베이스내의 모든 Link.
Dba_Ddl_locks : 데이터베이스내의 모든 DDL lock과 DDL lock이 현저하게
요구되는 사항에 관한정보.
Dba_dependencies : object 에 대한 Dependence.(REF, HARD)
Dba_directories : 데이터베이스내의 모든 directory objects.
Dba_Dml_locks : 데이터베이스내에 구성된모든 DML lock과 DML lock이
현저하게 요구되는사항에 관한정보.
Dba_errors : 데이터베이스내의 저장된 object에 대해 가장최근에 발생된 error.
Dba_exp_files : export파일에 대한 정보.
Dba_exp_objects : 점진적으로 export 되고있는 object에 대한 정보.
Dba_exp_version : 가장최근에 export된 session에 대한 version 정보.

Dba_extents : 데이터베이스내의 모든 세그먼트를 이루는 extents에 대한 정보.
Dba_free_space : 모든 테이블스페이스내의 free extents의 정보.
Dba_free_space_coalesced : 테이블스페이스내의 합쳐진 공간에 대한 통계정보.

Dba_indexes : 데이터베이스내의 모든 index. 통계정보를 얻기위해 Analyze를 사용.
Dba_ind_columns : 모든테이블과 클러스터에서 인덱스를 구성하는 칼럼에 대한정보.
Dba_ind_partitions : 각각의 index파티션에 대해서, 파티션정보, 파티션에대한
storage 매개변수, Analyze에 결정된 파티션통계자료.
Dba_jobs : 데이터베이스에 있는 모든 Jobs.
Dba_jobs_running : 데이터베이스내에 현재 실행중인 모든 Jobs.
Dba_libraries : 데이터베이스내의 모든 libraries.
Dba_lobs : 모든 테이블에 포함된 LOBs.
Dba_locks : 데이터베이스내에 생성된 모든 lock, latch과 lock,latch가
현저하게 요구되는 사항에 대한 정보.
Dba_method_params : 데이터베이스내에 type에 대한 method 매개변수.
Dba_method_results : 데이터베이스내에 type에 대한 method results.
Dba_nested_tables : 모든테이블내에 포함된 nested table에 대한 정보.
Dba_object_size : PL/SQL object에 대한 size, bytes.
Dba_object_tables : 데이터베이스내에 모든 object tables.
Dba_objects : 데이터베이스내에 모든 objects.(index partition, table partition,
package,package_body,trigger)
Dba_obj_audit_opts : 모든 table, view에 대한 감사 option.
Dba_part_col_statistics : 모든 table 파티션에 대한 칼럼통계와 그래프정보.
Dba_part_histograms : 모든 table 파티션의 histogram에 대한 데이터(endpoint).
Dba_part_indexes : 모든 partition index에 대한 정보.
Dba_part_key_columns : 모든 partition된 object에 대한 분할키칼럼정보.
Dba_part_tables : 모든 partition된 table에 대한 정보.
Dba_priv_audit_opts : 시스템과 user에 의해 감사를 받고있는 시스템 privileges.
Dba_profiles : 모든 profiles과 해당 profile의 limit을 나타냄.
Dba_queue_schedules : 메시지를 전달하는 schedule.
Dba_queue_tables : 데이터베이스내에 생성된 모든 queue테이블의
queue type의 name과 type.
Dba_Queus : 데이터베이스내의 모든 queue에 대한 동작특성.
Dba_rchild : refresh group 안의 모든 children object.
Dba_refresh : 모든 refresh group 에 대한 정보.
Dba_refresh_children : refresh group 안의 모든 object에 대한 정보.
Dba_refs : 데이터베이스내의 모든 테이블의 REF칼럼과, REF 속성을 가진 칼럼.
Dba_refistered_snapshot_groups : 모든 snapshot 사본 그룹.
Dba_registered_snapshots : 지역테이블의 원격snapshot 에 대한 정보.
Dba_rgroup : 모든 refresh group.
Dba_roles : 모든 데이터베이스내에 존재하는 roles.
Dba_role_privs : user와 role에 부여된 role에 대한 정보.
Dba_rollback_segs : rollback segments 에 대한 정보.
Dba_segments : 모든 데이터베이스 segment에 대한 할당된 storage에 대한 정보.
Dba_sequences : 모든 데이터베이스내의 sequences 에 대한 정보.
Dba_snapshot_logs : 모든 데이터베이스내의 snapshot_logs.
Dba_snapshot_refresh_times : snapshot refresh 한 시간.
Dba_snapshots : 모든 데이터베이스내의 snapshots.
Dba_source : 모든 데이터베이스내의 저장object 의 source를포함.
Dba_stmt_audit_opts : system, user에 의한 현재의 감사option에 대한 정보.
Dba_synonyms : 데이터베이스내의 모든 synonyms
Dba_sys_privs : user에게 부여된 system privilege와 role.
Dba_tab_col_statistics : Dba_tab_columns view에 있는정보에 대한 칼럼통계와
그래프정보
Dba_tab_columns : 모든 table, view, cluster에 대한 칼럼정보. Analyze명령어사용.
Dba_tab_comments : 데이터베이스내의 모든 table, view에 대한 주석.
Dba_tab_histograms : 모든 table의 칼럼에 대한 histogram.
Dba_tab_partitions : 각각의 table partition에 대해서, partition level의 partition정보와,
partition의 storage매개변수 ,Analyze 에의해 결정된 여러 partition통계정보.
Dba_tab_privs : 모든 데이터베이스내의 object에 부여된 권한.
Dba_tables : 모든 데이터베이스내의 관계형테이블에 관한정보.Analyze로
통계정보를 얻을수 있다.
Dba_tablespaces : 모든 테이블스페이스에 관한정보.
Dba_triggers : 모든 데이터베이스내의 trigger 정보.
Dba_trigger_cols : 모든 trigger에서 사용된 칼럼정보.
Dba_ts_quotas : 모든 user에게 할당된 tablespace.
Dba_type_attrs : 데이터베이스내의 type에 대한 속성.
Dba_type_methods : 데이터베이스내의 모든 type에 대한 methods.
Dba_types : 데이터베이스내의 모든 추상적데이터type.
Dba_updatable_columns : join view에서 데이터베이스관리자가
update할수있는칼럼정보.
Dba_users : 데이터베이스내의 모든 user정보.
Dba_views : 모든 데이터베이스내의 view의 text.
Dbms_alert!_info : 등록된 alert!정보.
Dbms_lock_allocated : 사용자에게 할당된 lock정보.
Deptree : utldtree.sql 에의해 생성되며, object의 dependency tree정보를 포함함.
'Sys' user인 경우. 이 object에 관련된 공유커서를 나타내고,
다른 user인 경우공유커서이외의 object를 나타낸다.
다른 user는 공유커서정보를 얻기위해, Sys.deptree를 access할수있다.

Dictionary : data dictionary table, view에 대한 정보.
Dict_columns : data dictionary table, view에 대한 칼럼.
Error_size : Dba_obejct_size 와 user_obejct_size view를 create 할때 사용된다.
Exceptions : 무결성제약조건에 위배되는 정보를 포함. utlexcpt.sql 로 생성.
File_lock : 병렬서버view. 초기화파라미터 GC_FILE_TO_LOCKS 에 명시된,
데이터파일에 PCM lock의 mapping정보.
File_ping : 병렬서버view.각데이타파일에 할당된 block의 수.
GC_FILES_TO_LOCKS 최적값을 구하기 위해 현존하는 데이터파일의
access방법을 결정하는데 이 정보를사용할 수 있다.
FILEXT$ : DBA_DATA_FILES 와 동일. (DBA_DATA_FILES의 사용을 추천)
GLOBAL_NAME : 현제 데이터베이스의 유일한 이름.
HS_ALL_CAPS : 모든 비 Oracle Data store (FDS) 와 관련된 특성에 관한정보.
HS_ALL_DD : 모든 비 Oracle Data store(FDS)에 대한 Data dictionary.
HS_ALL_INITS : 비 Oracle Data store(FDS)에 대한 초기화 매개변수.
HS_BASE_CAPS : 비 Oracle Data store(FDS)에 대한 기본특성에 관한정보.
HS_BASE_DD : 비 Oracle Data store(FDS)에 대한 Data dictionary.
HS_CLASS_CAPS : 비 Oracle Data store(FDS)에 포함된 class-specific 특성정보.
HS_CLASS_DD : 비 Oracle Data store(FDS) class_specific data dictionary.
HS_CLASS_INIT : 비 Oracle Data store(FDS) class-specific 초기화 매개변수.
HS_EXTERNAL_OBJECT_PRIVILEGES : user에게 부여된 object권한.
HS_EXTERNAL_OBJECTS : oracle server에서 access가능한 external obejct.
HS_EXTERNAL_USER_PRIVILEGES : 어느 특정object에 국한되지않은 모든
부여된권한
HS_FDS_CLASS : 비 oracle (FDS) class 에 관한 정보.
HS_FDS_INST : 비 oracle (FDS) instance에 관한정보.
HS_INST_CAPS : instance-specific 특성정보.
HS_INST_DD : 비 oracle (FDS) instance-specific data dictionary 변경정보.
HS_INST_INIT : 비 oracle (FDS) instance-specific 초기화 매개변수정보.
IDEPTREE : UTLDTREE.sql 로 생성하고, 관련tree를 나타냄.
Deptree의 자동정렬버젼.
INDEX_HISTOGRAM : Analyze index...validate structure 명령에 대한정보.
INDEX_STATS : 마지막 Analyze index..validate structure 명령에 대한정보.
NLS_DATABASE_PARAMETERS : 데이터베이스의 NLS 매개변수.
NLS_INSTANCE_PARAMETERS : instance의 NLS 매개변수.
NLS_SESSION_PARAMETERS : user session의 NLS 매개변수.

OBJ : user_objects 의 synonym.
PARSED_PIECES : Dba_object_size, User_object_size view를 생성시에 필요.
PARSED_SIZE : Dba_obejct_size, User_object_size view를 생성시에 필요.
Plan_table : explain plan의 결과에 대한 table. utlxplan.sql로 생성.
Product_component_version : Oracle 제품군의 버전과 상태설명.


Pstubtbl : Pstub utility에 의해 생성된 stub에 관한정보.
Publicsyn : public synonym 에 관한 정보.
Public_dependency : object와 관련된 dependencies.(parent object)
Resource_cost : 각각의 resource에 대한 cost.
Resource_map : 각각의 resource에 대한 정보.(resource name, resource number)
Role_role_privs : 다른 role에 부여된 role정보.(user가 access가능한 role에 한해)
Role_sys_privs : 다른 role에 부여된 system role정보(user가 access가능한role에 한해)
Role_tab_privs : 다른 role에 부여된 table privileges정보.
(user가 access가능한role에 한해)

SEQ : user_sequences 의 synonym.
Session_privs : 현재 user에게 사용가능한 권한.
Session_roles : 현재 user에게 사용가능한 roles.
Source_size : Dba_object_size, User_object_size view를 생성시 필요.
Stmt_audit_option_map : 감사 option type code정보.
Syn : user_synonyms 에 대한 synonym.
Synonyms : Oracle ver 5.와 호환성을 포함. not recommend
Syscatalog : Oracle ver 5.와 호환성을 포함. not recommend
Sysfiles : Oracle ver 5.와 호환성을 포함. not recommend
Syssegobj : Oracle ver 5.와 호환성을 포함. not recommend
System_privilege_map : system privilege code에 대한 정보.
Sys_objects : object ID와 object type 그리고 segment data block주소를 매핑하는정보.
Tab : Oracle ver 5.와 호환성을 포함. not recommend
Table_privileges : user가 부여한, 부여받은, 소유한, 그리고 PUBLIC으로
부여된 object 권한정보. Oracle ver 6.과 호환성을 포함. not recommend.
Table_privilege_map : access 가능한 권한code/권한명칭 정보.
Tabs : User_tables 의 synonym.
Tabquotas : Oracle ver 5.와 호환성을 포함. not recommend
Trusted_servers : 분산환경에서 서버가 신뢰할만한지를 나타냄.
Tp_pitr_check : catpitr.sql 에 의해 생성. 테이블스페이스의 point-in-time복구를
방해할지도 모르는 dependencies혹은 restriction에 관한 정보제공.
Ts_pitr_objects_to_be_dropped : 테이블스페이스의 point-in-time복구수행의 결과
손실된 object에 대한 정보. (point-in-time recovery의 경우만 해당).
User_all_tables : user가 사용가능한 테이블(object table, relational table)정보.
User_arguments : user가 access가능한 object의 매개변수정보.
User_Audit_object : cataudit.sql로 생성. object에 관련된 감사추적기록.
User_Audit_session : cataudit.sql로 생성. user의 연결/종료에 관련된 감사추적기록.
User_Audit_statement : cataudit.sql로 생성. user에 의해 실행된 GRANT,REVOKE,
AUDIT, NOAUDIT, ALTER SYSTEM 명령에 대한 감사추적기록.


User_Audit_trail : user와 관련된 전반적인 사항의 감사추적기록.
User_catalog : user 소유의 table, views, synonyms, sequences 의 이름과 type.
User_clusters : user소유의 cluster.
User_clu_columns : user table 의 칼럼과 cluster칼럼과의 매핑테이블.
User_col_comments : user 의 table, view의 칼럼에 대한 주석.
User_col_privs : user 가 소유한, 부여한, 부여받은 칼럼에 대한 권한.
User_col_privs_made : user 소유 object의 칼럼에 대한 권한.
User_col_privs_recd : user가 부여받은 칼럼에 대한 권한.
User_coll_types : user가 명명한 collection type정보.
User_constraints : user소유 테이블의 제약조건정의.
User_cons_columns : user소유 제약조건에 정의된 칼럼에 대한정보.
User_db_links : user소유 데이터베이스링크에 대한정보.
User_dependencies : user소유 object에 대한 dependencies.
User_errors : user소유 저장 object에 대한 현재의 에러.
User_extents : user소유 object에 속하는 세그먼트의 extent 정보.
User_free_space : user가 access가능한 테이블스페이스내의 free extent 정보.
User_indexes : user 소유의 indexes. Analyze명령을 사용해야함. 병렬서버를 지원.
User_ind_columns : user소유 index 또는 user소유 table 의 칼럼정보.
User_ind_partitions : user소유의 index partition각각에 대한설명과, partition정보,
partition의 storage 매개변수, Analyze명령으로 결정된 여러partition통계
User_jobs : user소유의 모든 job.(export/import!, execution)
User_libraries : user소유의 모든 libraries .
User_lobs : user소유의 table에포함된 LOBs정보.
internal LOBs( BLOBs, NCLOBs) 만해당, external LOBs(i.e, BFILES)은 아님.
User_method_params : user type의 method 매개변수.
User_method_results : user type의 method 의 results.
User_nested_tables : user소유 테이블에 포함된 nested tables.
User_object_tables : user가 사용가능한 object table.
User_objects : user소유의 object.(index partition, table partition, package,
packagebody, trigger)
User_object_size : user소유의 PL/SQL object.
User_obj_audit_opts : cataudit.sql로 생성. user소유의 table,view에 대한 감사option
User_part_col_statistics : user소유의 tablepartition정보에 대한 칼럼통계와 그래프정보.
User_part_histograms : user가 access할수있는 table partition의 histogram에 대한
그래프데이터(end-pointer).
User_part_key_columns : user소유의 partition object의 partition key칼럼에 대한정보.
User_part_indexes : 모든 user소유의 partition index의 partition정보.
User_part_tables : user소유의 partition table에 대한 object 레벨의 partition정보.


User_password_limits : user에게 적용된 password profile parameter.
User_queue_tables : user소유 스키마에 생성된 queue table내부의 queues정보.
User_Queues : user스키마의 모든 queue에 대한 동작 특성을 나타냄.
User_refresh : 모든 refresh group.
User_refresh_children : user가 소유한 refresh group 내부의 object에 관한정보.
User_refs : user소유테이블의 object type칼럼중 REF칼럼, REF속성.
User_resource_limits : 현재 user의 resource 한계.
User_role_privs : user에게 부여된 roles.
User_segments : user오브젝트에 포함된 데이터베이스 segments의 storage할당정보.
User_sequences : user 소유의 sequences.
User_snapshots : user 가 볼수있는 snapshots.
User_snapshot_logs : user 소유의 모든 snapshot logs.
User_source : user소유 저장 objects 의 모든 text source.
User_snapshot_refresh_times : snapshot refresh time.
User_synonyms : user소유의 synonym.
User_sys_privs : user에게 부여된 system 권한.
User_tab_col_statistics : user_tab_columns view에 대한 칼럼통계와
그래프정보를 나타냄.
User_tab_columns : user소유의 table, view, cluster의 칼럼정보.(Analyze명령사용)
User_tab_comments : user소유의 table, view에 대한 주석.
User_tab_histograms : user소유 table의 칼럼에 대한 histogram.
User_tab_partitions : user소유 table partition에 대한, partition 레벨의 분할정보와,
partition의 storage매개변수, Analyze에 의해 집계된 여러통계정보.
User_tab_privs : user가 소유한, 부여한, 부여받은 object에 대한 권한 정보.
User_tab_privs_made : user가 소유한 object에 관한 모든 권한.
User_tab_privs_recd : user가 부여받은 object 권한정보.
User_tables : user소유의 relational table에 대한 정보. (Analyze명령사용)
User_tablespaces : user가 access 가능한 tablespaces에 대한 설명.
User_triggers : user가 소유한 triggers 정보.
User_trigger_cols : user가 소유한 또는 user테이블에 있는 trigger안의 column 정보.
User_ts_quotas : user에게 할당된 tablespace quotas 정보.
User_types : 테이블안의 user소유의 type.
User_type_attrs : user type의 속성을 나타냄.
User_type_methods : user type의 methods를 나타냄.
User_updatable_columns : join view에서 사용자에게 update가 허용된 칼럼정보.
User_users : 현재 user에 관한 정보.
User_views : user 소유의 view에 대한 text.




FILEXT$ : 데이터파일의 AUTOEXTEND를 ON으로 변경했을 때 처음 생성.
V$ACCESS : 현재 데이터베이스내의 lock이걸린 object와 그 object를
access 하려는 session id.
V$ACTIVE_INSTANCES : 현재 데이터베이스내의 Mount된
모든 인스턴스에대하여 인스턴스 이름과, 번호를 매치.
V$AQ : 데이터베이스내의 모든 Queue에 대한 통계.
V$ARCHIVE : Archive에 필요한 redo log file에 대한 정보.
각각의 행은 하나의 thread에 대한 정보이다. V$LOG도 동일한정보.
V$ARCHIVE_DEST : 현재의 instance에서, 모든 archive log destination,
현재값, mode, status.
V$ARCHIVED_LOG : archive log 이름을 포함하는 controlfile에 대한 archive log 정보,
archive log 기록은 online중 redo log가 성공적으로 저장되었거나,
clear(log가 clear되면, name칼럼은 null이 된다)된후 insert된다.
V$BACKUP : 모든 online 데이터파일의 backup 상태를 나타낸다.
V$BACKUP_CORRUPTION : 데이터파일의 backup 중 에러정보를 나타낸다.
에러들은 control 파일과 achived log backup 에 포함되지 않는다.
V$BACK_DATAFILE : control 파일에서 datafile과 controlfile 의 backup정보를 보여줌.
V$BACK_DEVICE : 지원되는 backup 디바이스정보.
V$BACK_PIECE : controlfile에서 backup piece에 대한 정보를 포함.
각각의 backup set 은 하나 또는 그이상의 backup piece로 구성된다.
V$BACKUP_REDOLOG : controlfile에서 backup set의 저장된 log에 대한 정보.
Online redo logs는 곧바로 backup 되지 않는다: 먼저 disk에 저장된후 backup
된다. 저장된 log backup set 은 하나 또는 그이상의 logs들로 구성된다.
V$BACKUP_SET : controlfile에서 backupset 정보를 보여줌.
backup set 행은 backup set이 성공적으로 완료되었을 때 insert된다.
V$BGPROCESS : 백그라운드 프로세스 정보.
V$BH : 병렬서버 view이다.
SGA내의 모든 버퍼에 대한 ping의 상태와 수를 나타낸다.
V$BUFFER_POOL : 인스턴스내에서 사용가능한 모든 버퍼풀에 대한정보.
V$CACHE : 병렬서버 view이다.
특정데이타베이스object에 관련된 현재의 인스턴스의
SGA내부의 각각의 block에 대한 block header에 대한 정보.
V$CACHE_LOCK : 병렬서버view. platform-specific lock manager 식별자를 제외하면,
V$CACHE와 유사하다.
V$CIRCUIT : 가상 circuit에 관한 정보이며, 가상circuit란 dispatcher와 server를
통한 데이터베이스와의 user 연결을 말한다.
V$CLASS_PING : 각각blockclass마다 ping된 블록의 수를나타낸다.
다른class블록의 충돌을 비교하기위해 사용.
V$COMPATIBILITY : 이전버전으로 downgrade를 방지하기위해
데이터베이스인스턴스에 의해 사용된특성들을 설명.
다른 인스턴스가 갖고있는 특성에 영향을 미치지 않으며,
데이터베이스가 완전히 정지한이후에도 존재하지 않는 일시적인
비호환성들을 포함할수도 있다.
V$COMPATSEG : 이전버전으로 되돌아가는 것을 막기위한 데이터베이스에서
사용되는 영구적인 특성들.
V$CONTROLFILE : 컨트롤파일의 이름과 상태.
V$CONTROLFILE_RECORD_SECTION : 컨트롤파일의 record에 대한 정보.
V$COPY_CORRUPTION : 컨트롤파일로부터 데이터파일의 복사불량에 대한 정보.
V$CURRENT_BUCKET : 캐쉬내의 버퍼의 수가 감소할때 발생할 수 있는
캐쉬손실의 경우수를 예상하는데 유용.
V$DATABASE : control file 로부터 데이터베이스정보를 포함.
V$DATAFILE : 컨트롤파일로부터데이타파일에대한 정보를 포함.
V$DATAFILE_COPY :컨트롤파일로부터 데이터파일의 복사에 대한 정보를포함.
V$DATAFILE_HEADER : 데이터파일헤더에 대한 정보.

V$DBFILE : 데이터베이스를 구성하는 모든 데이터파일.
대신에 V$DATAFILE 추천한다.
V$DBLINK : 세션에 의해 open된 데이터베이스링크에 대한 설명.
이 데이터베이스링크들은 닫히기전에 commit되거나 rollback되어야만 한다.

V$DB_OBJECT_CACHE : library cache에 cach된 데이터베이스오브젝트를 나타냄.
V$DB_PIPES : 데이터베이스내에 현재 운영중인 pipe에 대한 설명.
V$DELETED_OBJECT : 삭제된 archived 로그, 데이터파일 copy,
컨트롤파일에서 백업piece 에 대한 정보. 이뷰의 목적은 복구목록의
재동조작업을 최적화하는 것이다. archived 로그나, 데이터파일 copy,
백업piece 등이 삭제될때는 해당하는 행이삭제되었음이 표시된다.
V$DISPATCHER : dispatcher 프로세스에 관한 정보.
V$DISPATCHER_RATE : dispatcher 프로세서에 관련된 확률통계.
V$DLM_CONVERT_LOCAL : lock 변환작업에 대한 경과시간.
V$DLM_CONVERT_REMOTE : 원격 lock변환작업에 대한 경과시간.
V$DLM_LATCH : DLM 잠금에 대한 통계.
각각의 잠금에 대한 통계보다는, 각 타입에 대한 총계를 포함.
개념적으로 IMM_GETS/TTL_GETS 값은 1에 가깝게 된다.
V$DLM_LOCKS : 병렬서버 view이다. 블록화되었거나, 다른 것을
블록화하고있는 lock manager에 알려진 모든 lock에 대한 정보.
V$DML_MISC : 잡다한 DLM 통계에 대한 정보.
V$ENABLEDPRIVS:사용가능한 권한에 대한정보, 이들권한은
SYS.SYSTEM_PRIVILEGES_MAP테이블에 존재해야만 한다.
V$ENQUEUE_LOCK : 큐에 대기상태인 오브젝트에의해 소유된 모든 lock이
view의 칼럼은 V$LOCK의 칼럼과 동일하다.
자세한 것은 V$LOCK을 참고.
V$EVENT_NAME : wait event 에 대한 정보.
V$EXECUTION : 병렬 질의 실행에 대한 정보.
V$EXECUTION_LOCATION : 병렬 질의 실행 트리의 위치에 대한 자세한 정보.
V$FALSE_PING : 병렬서버view. ping에 실패지도 모르는 버퍼에 대한 정보.
즉, 10회이상ping된 다른 버퍼와
동일한 lock으로 잠겨있는 버퍼를 말한다.
ping이 실패로 판명된 버퍼는 lock충돌을 감소시키기위해
1-44페이지의 "GC_FILES_TO_LOCK"에 다시 매핑된다.
V$FILE_PING : 데이터파일마다 ping된 블록수를 보여줌. 이정보는 현존하는
데이터파일에 대한 access패턴을 결정하는데 and,
데이터파일블록을 PCM lock에 새로 매핑하는것을 결정하는데 사용된다.
V$FILESTAT : 파일 read/write 통계.
V$FIXED_TABLE : 데이터베이스내의 모든 동적실행테이블, views, 유도테이블.
실제테이블을 참조하는 약간의 V$테이블은 리스트에 없다.
V$FIXED_VIEW_DEFINITION : (V$로 시작하는)고정view에 대한 설명.
유의해서 사용해야한다.
V$GLOBAL_TRANSACTION : 현재 활동중인 트랜잭션에 대한 설명.
V$INDEXED_FIXED_COLUMN : index된 동적실행테이블(X$ table)의 칼럼에
대한 설명. X$ table은 경고없이 변경할수있다.
이view는 보다 효과적으로 고정뷰(V$view)에 대한
V$INSTANCE : 현재의 인스턴스의 상태를 나타냄.
V$INSTANCE의 버전은 V$INSTANCE의 초기버전과 호환성이 없다.
V$LATCH : 하위 잠금에 대한 통계와 상위 잠금에 대한 요약통계.
즉, 상위잠금에 대한 통계는 그 하위잠금에 대한 각각의 통계를 포함한다.
V$LATCHHOLDER : 현재잠금에 대한 정보.
V$LATCHNAME : V$LATCH 에 있는 잠금에 대한 디코드된 잠금이름에 대한
정보. V$LATCHNAME의 행들은 V$LATCH의 행들과 1:1로 대응된다.

V$LATCH_CHILDREN : 하위잠금에 대한 통계를 포함.
V$LATCH의 칼럼에 child# 칼럼이추가되었다. LATCH#칼럼이 서로
동일하다면, 하위잠금이 동일한 상위잠금을 갖는 것이다.
V$LATCH_MISSES : 잠금을 획득하는데 실패한 시도에 대한 통계.
V$LATCH_PARENT : 상위잠금에 대한 통계.
V$LATCH_PARENT 칼럼은 V$LATCH칼럼과 동일하다.
V$LIBRARYCACHE : library cache의 실행과 활동통계.
V$LICENSE : license 한계에 대한 정보.
V$LOADCSTAT : 직접적재하는동안 컴파일된 SQL*loader 통계정보.
이테이블에대한 어떤 Select 문도 "no rows returned" 결과가 나오는데,
왜냐면, 동일한 시간에 데이터를 적재하면서, 쿼리를 날릴수 없기 때문이다.

V$LOCK : 현재 Oracle 서버에 의해 확립된 잠금에 대한 정보나 lock또는
latch에 대한 두드러진요청
V$LOCK_ACTIVITY : 병렬서버view이다. V$LOCK_ACTIVITY는 현재의
인스턴스의 DLM잠금동작을 나타낸다.
각각의 행은 잠금동작의 타입과 일치된다.
V$LOCK_ELEMENT : 병렬서버view이다. 버퍼캐쉬에 의해사용된 각각의
PCM잠금에 대해 v$LOCK_ELEMENT 에 한행이다.
잠금요소에 대응되는 PCM잠금의 이름은 'BL',indx,class등이다.
V$LOCKED_OBJECT : 시스템안의 모든 트랜잭션에 걸린 잠금을 나타낸다.
V$LOCKED_WITH_COLLISIONS : 병렬서버view이다.
여러버퍼를 보호하는 lock을 찾는데 사용되며, 그 버퍼들은 최소한
10회이상 각각 강제로 쓰여지거나, 강제로 읽혀진 버퍼들이다.
V$LOG : 컨트롤파일로부터 log 파일정보를 포함한다.
V$LOGFILE : redo log 파일정보. redo log 그룹과 멤버 파일명.
V$LOGHIST : 컨트롤파일로부터 log history정보를 포함. 지속적인 호환성을
포함하고 있다. 대신에 V$LOG_HISTORY의 사용을 권장한다.
V$LOG_HISTORY : 컨트롤파일로부터 log history 정보를 포함한다.
V$MLS_PARAMETERS : Oracle Server의 확정된 초기화파라미터를 나타냄.
V$MTS : multi-threaded server의 성능향상을위한 정보를 포함.
V$MYSTAT : 현재 세션에 대한 통계값포함.
V$NLS_PARAMETERS : 현재의 NLS 매개변수의 값들을 포함.
V$NLS_VALID_VALUES : 유효한 NLS 매개변수값.
V$OBJECT_DEPENDENCY : 현재 공유풀에 적재되어있는 package, procedure,
cursor등에 관련되어있는 object를 결정하는데 사용된다.
예를들면, V$SESSION, V$SQL등과 조인하면, 현재 어떤 user가
실행중인 SQL문에서 어떤 테이블이 사용되었는지를 알아낼수가 있다.
V$OFFLINE_RANGE : 컨트롤파일로부터 offline된 datafile을 보여준다.
DATAFILE행에 저장되어있는 각각의 데이터파일의 최종offline 간격을
보여줌. offline 간격은 테이블스페이스가 처음 offline normal,
또는 Read Only로 변경되고난이후 다시 online 또는 read-write로
변경된다음에 확정된다.
데이터파일이 스스로 Offline로 변경되거나 테이블스페이스가
OFFLINE IMMEDIATE로 변경되면, offline간격은 확정되지 않는다.

V$OPEN_CURSOR : 각각 user 세션이 열렸있거나, 정지되어있는 cursor를 보여준다.
V$OPTION : Oracle Server와 같이 설치된 선택사항들.
V$PARAMETER : 초기화 파라미터에 대한 설명이다.
V$PING : 병렬서버view이다.
최소한 1번이상 ping된 블록만을 보여준다는 것을 제외하고 V$CACHE view와
동일하다.특정 데이터베이스 object와 관련된 현재의 인스턴스내의 SGA에
있는 각각의 블록에대한 block header정보를 포함하고 있다.
V$PQ_SESSTAT : 병렬쿼리에 대한 session 통계를 포함.
V$PQ_SLAVE : 인스턴스내에 실행중인 parallel 쿼리서버에 대한 통계.
V$PQ_SYSSTAT : 병렬쿼리에 대한 시스템통계.


V$PQ_TQSTAT : 병렬쿼리 동작의 통계를 포함. 통계는 질의가 완료된후에
컴파일되며 세션이 살아있는동안 계속 남아있는다.
V$PROCESS : 현재 작업중인 프로세스에 대한 정보.
LATCHWAIT 칼럼은 프로세스잠금이 무엇을 기다려야하는가를 나타내며,
LATCHSPIN 칼럼은 프로세스잠금이 동작되는 것을 나타낸다.
멀티프로세서의 경우 Oracle 프로세스는 잠금을 기다리기전에 실시한다.
V$PWFILE_USERS : password 파일로부터 유도해낸
SYSDBA, SYSOPER 권한을 부여받은 user.
V$QUEUE : 멀티쓰레드 메시지큐에 대한 정보.
V$RECENT_BUCKET : 대용량 캐쉬실행을 평가하기에 유용한 정보.
V$RECOVER_FILE : media 복구에필요한 파일의 상태를 나타냄.
V$RECOVERY_FILE_STATUS : 각각의 RECOVER명령에 대한 각 데이터파일에
대한 정보를 한행씩 포함.
Oracle프로세스가 복구를 수행하는데 유용한 정보임.
recover manager는 서버프로세스에 직접 복구를수행하도록 했을 때,
recovery manager가 이 view에서 관련된정보를 참고할 수 있다.
다른user들에게는 유용하지 않다.
V$RECOVERY_LOG : 완벽한 media복구에 필요한 archived logs에 관한 정보.
이정보는 log history view인 V$LOG_HISTORY에서 유도된 것이다.
V$RECOVERY_PROGRESS : 데이터베이스복구작업이 중간에 멈추지않도록하는데
사용되며, 복구작업을 완료하는데 요구되는 시간을 측정하는데 사용된다.
V$RECOVERY_STATUS : 현재의 복구진행상태를 나타낸다. 단지 복구를 수행하는
Process 에대한 정보만이유용하다. 복구관리자가 서버프로세스에게 복구를
수행하라고 지시할때에, 복구관리자는 이view에서
관련정보를 참조할 수 있다. 다른 user에게는 불필요하다.
V$REQDIST : MTS dispatcher의 응답시간에 대한 그래프통계를 나타내며,
time range는 버킷 number의 지수함수로 증가한다.
V$RESOURCE : 자원(resource)의 이름과 주소정보를 포함.
V$RESOURCE_LIMIT : System 자원의 부분적인 사용에 대한 정보. 자원의
소비를 모니터링함으로서 낭비를 방지하는데 사용된다.

V$ROLLNAME : 모든 online중인 rollback segments의 이름.
데이터베이스가 open시에만 조회가능.
V$ROLLSTAT : 롤백세그먼트통계정보.
V$ROWCACHE : 자료사전활동에 대한 통계.
각각의 행은 하나의 자료사전cache 통계를 포함.
V$SESSION : 현재 open된 세션에 대한 정보.
V$SESSION_CONNECT_INFO : 현재의 세션에 대한 network 연결에 대한 정보.
V$SESSION_CURSOR_CACHE : 현재의 세션에 대한 cursor 사용에 대한 정보.
SESSION_CACHED_CURSORS 초기화파라미터에 대한 효율을 측정하지는
않는다.
V$SESSION_EVENT : 세션의 event 대기에 관한정보.
V$SESSION_LONGOPS : 장시간실행되는 작업에 대한 상태. SOFAR,
TOTALWORK칼럼은 진행상태를 제공한다. 예를들어
다음요소(hach cluster creations, backup, recovery) 에 대한
작동상태를 모니터링할 수 있다.
V$SESSION_OBJECT_CACHE : 로칼서버의 현재사용중인
user세션의 object, cache통계정보.
V$SESSION_WAIT : 활동중인 세션이 대기하고있는 자원또는 이벤트이다.
V$SESSTAT : user세션 통계이다. 통계number(statistic#)에 해당하는
통계name을 찾으려면, V$STATNAME를 참고하면 된다.
V$SESS_IO : 각각의 user세션에 대한 I/O 통계이다.
V$SGA : System Global Area 에대한 간략한 정보.(name, size)
V$SGASTAT : System Global Area에 대한 자세한 정보.(name, bytes, pool)

V$SHARED_POOL_RESERVED : Shared Pool내에 예약풀과 공간을
바꾸고자할 때 도움이 되는통계.
V$SHARED_SERVER : Shared Server processes 에 대한 정보를 포함.
V$SORT_SEGMENT : 주어진 인스턴스내의 각 sort세그먼트에 대한 정보.
테이블스페이스가 Temporary 타입일때만 update된다.

V$SORT_USAGE : sort 사용에 대해 기술한다.
V$SQL : Group by절이없는 공유sql영역에대한 통계이며 입력된
원래 sql문장의 각 child의 row를 포함.
V$SQL_BIND_DATA : 데이터가 이 서버에서 추출가능하다면 이 view를
조회하는 세션에 소유된 각 커서안에 있는 각각의 원격bind변수에 대한
클라이언트에 의해 보내진 데이터.
V$SQL_BIND_METADATA : 이view를 조회하는 세션에 소유된 각커서안에 있는
각각의 원격bind변수에 대해 클라이언트에의해 제공되는 bind metadata.

V$SQL_CURSOR : 이 view를 조회하는 세션과 관련된 각 cursor에 대한 디버깅정보.
V$SQL_SHARED_MEMORY : 메모리 스냅샷에 공유된 커서에 대한 정보.
공유풀에 저장된 각SQL문은 관련된 하나또는 그이상의 하위object를
가지고 있다.
V$SQLAREA : 공유SQL영역에 대한 통계를 가지고있으며, Sql 문자열마다
한행을 포함한다. 메모리내에 존재하는, parse된, 실행을 대기하고있는
SQL문장에 대한 통계를 제공한다.
V$SQLTEXT : SGA내부의 공유SQL 커서에 속해있는 SQL문장을 포함.
V$SQLTEXT_WITH_NEWLINES : 가독성이 증가되고, 공백을 포함한 SQL문장안에
newline과 tabs을 대체하지 않는다는 것을 제외하고는 V$SQLTEXT view와
동일하다.
V$STATNAME : V$SESSTAT와 V$SYSSTAT테이블에서 나타난 statistics에 대한 이름.
V$SUBCACHE : 현재 라이브러리 캐쉬메모리에 적재된 하위 캐쉬에 대한 정보.
모든 라이브러리캐쉬에 대해 언급하고있으며, 각 라이브러리 캐쉬object마다
각 적재된 하위 캐쉬에 대해 한행을 나타낸다.
V$SYSSTAT : 시스템 통계이다. 각 statistic number(statistic#)와 관련된 statistic의
이름을 찾기위해서는, "V$STATNAME"를 보시오.
V$SYSTEM_CURSOR_CACHE : 시스템 전반적인정보라는 것을 제외하고,
V$SESSION_CURSOR_CACHE와 유사한 정보를 나타낸다.
V$SYSTEM_EVENT : 이벤트에 대한 총 wait정보. TIME_WAITED,
AVERAGE_WAIT칼럼은 급속메커니즘을 지원하지 않는 플랫폼에서
0값을 포함할 것이다. 이런 플랫폼에서 DB를 운영중이고,
이칼럼이 wait time을 줄여주기를 원한다면, 파라미터파일의
TIMED_STATISTICS를 TRUE로 세팅하면된다.
단지 이렇게 하면, 시스템 성능에 약간의 마이너스효과를 가져올 것이다.
V$SYSTEM_PARAMETER : System parameter에 대한 정보.
V$TABLESPACE : 컨트롤파일로부터 테이블스페이스 정보를 나타내준다.
V$THREAD : 컨트롤파일로부터 thread 정보를 가져온다.
V$TIMER : 1/100 초로 나타낸 경과시간. 시간은 epoch가 시작된이후부터
측정되며, epoch는 OS의 특성이며, 값이 4bytes(약 497일)를 넘을때마다
0근처의 값이 된다.
V$TRANSACTION : 시스템내의 활동중인 트랜잭션.
V$TRANSACTION_ENQUEUE : 트랜잭션 오브젝트에 의해 소유된 lock를 나타냄.
V$TYPE_SIZE : 데이터블록용량을 측정하는데 사용되는 여러
데이터베이스컴포넌트들의 SiZe.
V$VERSION : Oracle Server의 core 라이브러리 컴포넌트의 Version수이다.
각 컴포넌트에 한 row가 있다.
V$WAITSTAT : 블록점유에 대한 통계. 통계가 사용가능한 시간에만 갱신된다.

출처 : Tong - 늘푸른 소나무(松)님의 오라클-SQL통

Posted by 1010
02.Oracle/DataBase2009. 11. 27. 15:34
반응형

SQL문 튜닝 개요

Added by honghoekim, last edited by honghoekim on 7월 31, 2009

Labels:

Enter labels to add to this page:
Wait Image 
Looking for a label? Just start typing.

1.문제가 있는 SQL 식별

1)느린 프로그램을 식별
2)프로그램에서 SQL을 검토
3)SQL_Trace 및 TKPROF를 사용

  • SQL문 식별이 불가능한 경우(SQL이 동적으로 생성되는 경우) SQL TRACE를 사용하여 실행된 SQL을 포함하는 Trace file을 생성한 다음 TKPROF를 사용하여 출력 파일을 생성

2.Optimizer 통계 확인

1)모든 테이블에 대한 통계를 수집

  • 모든 SQL문의 실행 계획을 결정하는 CBO는 테이블 및 인덱스에 대해 수집된 통계를 사용함.통계가 수집되지 않았거나 통계가 데이터베이스에 저장된 데이터를 대표하지 못할 경우 Optimizer에 정보가 부족해 최상의 계획을생성할 수 없다.

3.실행 계획 검토

다음 사항을 검토

1)Driving table이 최상의 필터를 가지는 계획이 되어야 한다.
2)각 단계의 조인 순서는 가장 적은 수의 행이 다음 단계로 반환됨을 의미 한다.
3)조인 방식이 반환되는 행 수에 적합.예를 들어 인덱스를 통한 중첩 루프 조인은 많은 행이 반환될 때 최적화되지 않을 수 있다.
4)뷰가 효율적으로 사용 된다.뷰에 대한 access 필요 여부 확인
5)작은 테이블에도 비의도적인 cartesian product가 없다.
6)각 테이블이 효율적으로 액세스 된다.

4.SQL문 재구성

1)AND 및 = 를 사용
2)WHERE절에 변환된 열이 포함되지 않도록 함

  • 술어 절 또는 WHERE절에 SQL 함수 사용 금지
    3)복합 모드 표현식을 빼고 암시적인 유형 변환에 유의
    4)각 작업에 대해 별도의 SQL문을 작성
  • 다양한 작업에 대해 하나의 SQL문을 사용할 경우 각 작업에 최적화 되지 않은 결과 나옴.굳이 하나의 SQL문을 사용해야 할 경우 UNION ALL 연산자를 사용
    5)서브 쿼리에 대해 IN 대신 EXISTS를 사용
    -선택적 술어가 서브 쿼리에 있는 경우는 IN을 사용.선택적 술어가 상위 쿼리에 있는 경우는 EXISTS를 사용
    6)힌트로 엑세스 경로 및 조언 순서를 제어
    -인덱스를 통해 필요한 행을 얻는 것이 더 효율적인 경우 전체 테이블 스캔 사용 금지,
    더 적은 수의 행을 Fetch하는 다른 인덱스를 대신 사용할 수 있다면 Driving 테이블에서 많은 수의 행을 Fetch하는 인덱스의 사용을 피하자,
    조인 순서에서 나중에 테이블에 적은 수의 행을 조인하는 조인 순서를 선택

5.인덱스 재구성

1)비선택적 인덱스를 제거하여 DML 속도를 높임
2)성능에 중요한 액세스 경로를 인덱스화함
3)기존에 연결된 인덱스에서 열 순서를 변경
4)인덱스에 열을 추가하여 선택성을 높임
5)IOT를 고려

6.시간 경과에 따른 실행 계획 유지 관리


출처 : http://www.javastudy.co.kr:8080/pages/viewpage.action?pageId=786591

Posted by 1010
02.Oracle/DataBase2009. 11. 25. 17:56
반응형
- http://www.oracle.com/technology/software/tech/java/sqlj_jdbc/index.html
  • Oracle Database 11g Release 1 (11.1.0.7.0) JDBC Drivers
    ojdbc5.jar (1,890,499 bytes) - Classes for use with JDK 1.5.
    ojdbc6.jar (1,988,051 bytes) - Classes for use with JDK 1.6.
  • Oracle Database 11g Release 1 (11.1.0.6.0) JDBC Drivers
    ojdbc5.jar (1,879,860 bytes)
    ojdbc6.jar (1,977,267 bytes)
  • Oracle Database 10g Release 2 (10.2.0.4) JDBC Drivers
    classes12.jar (1,609,607 bytes) - for use with JDK 1.2 and JDK 1.3
    ojdbc14.jar (1,555,682 bytes) - classes for use with JDK 1.4 and 1.5
  • Oracle Database 10g Release 2 (10.2.0.3) JDBC Drivers
    classes12.jar (1,600,090 bytes) - for use with JDK 1.2 and JDK 1.3
    ojdbc14.jar (1,545,954 bytes) - classes for use with JDK 1.4 and 1.5
  • Oracle Database 10g Release 2 (10.2.0.2) JDBC Drivers
    classes12.jar (1,594,191 bytes) - for use with JDK 1.2 and JDK 1.3
    ojdbc14.jar (1,540,457 bytes) - classes for use with JDK 1.4 and 1.5
  • Oracle Database 10g Release 2 (10.2.0.1.0) JDBC Drivers
    classes12.jar (1,590,491 bytes) - for use with JDK 1.2 and JDK 1.3
    ojdbc14.jar (1,536,979 bytes) - classes for use with JDK 1.4 and 1.5
  • Oracle Database 10g 10.1.0.5 JDBC Drivers
    classes12.jar (1,442,469 bytes) - for use with JDK 1.2 and JDK 1.3
    ojdbc14.jar (1,378,346 bytes) - classes for use with JDK 1.4
  • Oracle Database 10g 10.1.0.2 JDBC Drivers
    classes12.jar (1,417,089 bytes) - for use with JDK 1.2 and JDK 1.3
    ojdbc14.jar (1,352,918 bytes) - classes for use with JDK 1.4
  • Oracle9i 9.2.0.8 JDBC Drivers
    ojdbc14.jar - JDBC classes (1,212,964 bytes) - For use with JDK 1.4
    classes12.jar - JDBC classes (1,234,433bytes) - For use with JDK 1.2 and JDK 1.3
    classes111.jar - JDBC classes (1,063,074 bytes) - For use with JDK 1.1
  • Oracle9i 9.2.0.5 JDBC Drivers
    ojdbc14.jar - JDBC classes (1,200,046 bytes) - For use with JDK 1.4
    classes12.zip - JDBC classes (1,232,604 bytes) - For use with JDK 1.2 and JDK 1.3
    classes111.zip - JDBC classes (1,063,479bytes) - For use with JDK 1.1
  • Oracle9i 9.2.0.4 JDBC Drivers
    ojdbc14.jar - JDBC classes (1,187,584 bytes) - For use with JDK 1.4
    classes12.zip - JDBC classes (1,219,950 bytes) - For use with JDK 1.2 and JDK 1.3
    classes111.zip - JDBC classes (1,052,833 bytes) - For use with JDK 1.1
  • Oracle9i 9.2.0.3 JDBC Drivers
    ojdbc14.jar - JDBC classes (1,181,679 bytes) - For use with JDK 1.4
    classes12.zip - JDBC classes (1,213,897 bytes) - For use with JDK 1.2 and JDK 1.3
    classes111.zip - JDBC classes (1,048,261 bytes) - For use with JDK 1.1
  • Oracle9i 9.2.0.1 JDBC Drivers
    ojdbc14.jar - JDBC classes ( 1,174,976 bytes) - For use with JDK 1.4
    classes12.zip - JDBC classes ( 1,207,068 bytes) - For use with JDK 1.2 and JDK 1.3
    classes111.zip - JDBC classes ( 1,043,528 Bytes) - For use with JDK 1.1
  • Oracle9i 9.0.1.4 JDBC Drivers
    classes12.zip - JDBC classes (1,143,559 bytes) - For use with JDK 1.2 and JDK 1.3
    classes111.zip - JDBC classes (988,625 bytes) - For use with JDK 1.1
  • Oracle9i 9.0.1 JDBC Drivers
    classes12.zip - JDBC classes( 1,081 kb) - For use with JDK 1.2 and JDK 1.3
    classes111.zip - JDBC classes ( 936 kB) - For use with JDK 1.1
  • Oracle8i 8.1.7.1JDBC Drivers
    classes12.zip - JDBC classes ( 1,892 kB) - For use with JDK 1.2
    classes111.zip - JDBC classes ( 1,741 kB)


출처 : http://pantarei.tistory.com/tag/oracle

Posted by 1010
02.Oracle/DataBase2009. 11. 5. 18:07
반응형

EyeQ MC - Developer Site

오라클 10g 이상에서 expdp와 impdp를 사용한 tablespace 복사 방법

- 복사할 원본 tablespace 이름은 “SRC”, 사용자는 “SRC_USER”라 한다. - 복사 대상 tablespace 이름은 “COPY”, 사용자는 “COPY_USER”라 한다. - system 권한이 있어야 한다.(password는 “manager”)

< 순서 >

1. 복사본 tablespace 및 사용자 생성

2. Dump 디렉토리 설정

3. 원본 export

4. 원본 import


1. 복사본 tablespace 및 사용자 생성(SQL-Plus 로긴 필요)

ⅰ)	tablespace 생성
	CREATE TABLESPACE copy
		DATAFILE 'C:\ORACLExe\ORADATA\XE\copy00.dbf' SIZE 100M
		DEFAULT STORAGE 
		(	INITIAL    500K
 			NEXT      10K
 			MINEXTENTS 2
 			MAXEXTENTS 50
			PCTINCREASE 50);
		
ⅱ)	사용자 생성 및 권한 부여(패스워드는 동일)
	create user copy_user
		identified by copy_user
		default tablespace copy;
	
	grant connect,resource to copy_user;
	grant create table, create sequence, create view TO copy_user;
	
ⅲ)	데이타 파일 추가(사이즈에 맞게 설정)
	ALTER TABLESPACE copy
	ADD DATAFILE 'C:\ORACLExe\ORADATA\XE\copy01.dbf' SIZE 100M
	AUTOEXTEND ON NEXT 10M
	MAXSIZE 1G;	
	

2. Dump 디렉토리 설정(SQL-Plus 로긴 필요)

ⅰ) dump 받을 디렉토리 설정
	CREATE OR REPLACE DIRECTORY expdpDIR AS 'C:\temp';
ⅱ) 설정된 디렉토리 확인
	select * from dba_directories;
	
ⅲ)	디렉토리에 대한 권한 부여
	grant read, write on directory expdpDIR to system,src_user,copy_user;

3. 원본 export

ⅰ)	오라클(10g) 설치 디렉토리의 bin 디렉토리로 이동
ⅱ) export 실행
	expdp system/manager SCHEMAS=SRC directory=expdpdir dumpfile=expdpSRC.dmp job_name=SRC_JOB logfile=SRC_exp.log
	

4. 원본 import

ⅰ) 오라클(10g) 설치 디렉토리의 bin 디렉토리로 이동
ⅱ) import 실행
	impdp system/manager REMAP_SCHEMA=SRC:COPY REMAP_TABLESPACE=SRC:COPY directory=expdpDIR dumpfile=expdpSRC.dmp job_name=COPY_JOB logfile=COPY_imp.log

ⅲ) 메시지 확인
	"작업이 16:46:13에서 성공적으로 완료됨"
 
oracle_tablespace_copy.txt · 마지막 수정: 2008/12/05 11:41 작성자 jsmoon
 
Posted by 1010
02.Oracle/DataBase2009. 11. 5. 18:04
반응형
제품 : ORACLE SERVER

작성날짜 : 2004-05-28

10G DATAPUMP: REMAP TABLESPACE 기능
===================================


PURPOSE


이 문서는 datapump의 REMAP_TABLESPACE 파라미터를 사용하여 데이터베이스 객체를
하나의 테이블 스페이스에서 다른 테이블스페이스로 옮기는 방법을 설명하는 것을 목적으로
한다.

Explanation

Example


범위와 적용 방안


데이터베이스 관리자 - 오라클 기술 지원 애널리스트

다음은, REMAP_TABLESPACE 기능을 사용하여 데이터베이스 객체를 하나의 테이블스페이스로 부터
다른 테이블스페이스로 옮기는 예제를 보여주고 있다.

이 작업은 datapump 임포트에를 통해 수행되며, 다음 세개의 datapump 명령에 의해 소스 스키마로 부터
객체를 추출 할 수 있다.

expdp SYSTEM/password TABLES=<schemaname.tablename>
expdp SYSTEM/password SCHEMAS=<schema>
expdp SYSTEM/password FULL=y

다음은 Scott의 객체를 NewScott의 스키마로 datapump export 명령에 의해 추출하는 절차를
보여준다.

expdp SYSTEM/manager SCHEMAS=scott DIRECTORY=dpump_dir1 DUMPFILE=hr.dmp

=====================

sun1/home/prod/scmiller> sqlplus

SQL*Plus: Release 10.1.0.2.0 - Production on Tue Dec 23 14:29:18 2003

Copyright (c) 1982, 2003, Oracle. All rights reserved.

Enter user-name: / as sysdba

Connected to:
Oracle Database 10g Enterprise Edition Release 10.1.0.2.0 - Production
With the Partitioning, OLAP and Data Mining options

SQL> create directory dpump_dir1 as '/home/prod/scmiller';

Directory created.

SQL> grant read, write on directory dpump_dir1 to public;

Grant succeeded.

SQL> exit
Disconnected from Oracle Database 10g Enterprise Edition Release 10.1.0.2.0 -
With the Partitioning, OLAP and Data Mining options

sun1/home/prod/scmiller> expdp system/manager schemas=scott
DIRECTORY=dpump_dir1 DUMPFILE=newtbs.dmp

Export: Release 10.1.0.2.0 - on Tuesday, 13 January, 2004 12:29

Copyright (c) 2003, Oracle. All rights reserved.

Connected to: Oracle Database 10g Enterprise Edition Release 10.1.0.2.0 -
With the Partitioning, OLAP and Data Mining options
FLASHBACK automatically enabled to preserve database integrity.
Starting "SYSTEM"."SYS_EXPORT_SCHEMA_01": system/******** schemas=scott DIRECT
Estimate in progress using BLOCKS method...
Processing object type SCHEMA_EXPORT/TABLE/TABLE_DATA
Total estimation using BLOCKS method: 192 KB
Processing object type SCHEMA_EXPORT/USER
Processing object type SCHEMA_EXPORT/SYSTEM_GRANT
Processing object type SCHEMA_EXPORT/ROLE_GRANT
Processing object type SCHEMA_EXPORT/DEFAULT_ROLE
Processing object type SCHEMA_EXPORT/SE_PRE_SCHEMA_PROCOBJACT/PROCACT_SCHEMA
Processing object type SCHEMA_EXPORT/TABLE/TABLE
Processing object type SCHEMA_EXPORT/TABLE/INDEX/INDEX
Processing object type SCHEMA_EXPORT/TABLE/CONSTRAINT/CONSTRAINT
Processing object type SCHEMA_EXPORT/TABLE/INDEX/STATISTICS/INDEX_STATISTICS
Processing object type SCHEMA_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS
Processing object type SCHEMA_EXPORT/TABLE/CONSTRAINT/REF_CONSTRAINT
. exported "SCOTT"."DEPT" 5.656 KB 4 rows
. exported "SCOTT"."EMP" 7.820 KB 14 rows
. exported "SCOTT"."SALGRADE" 5.585 KB 5 rows
. exported "SCOTT"."BONUS" 0 KB 0 rows
Master table "SYSTEM"."SYS_EXPORT_SCHEMA_01" successfully loaded/unloaded
******************************************************************************
Dump file set for SYSTEM.SYS_EXPORT_SCHEMA_01 is:
/home/prod/scmiller/newtbs.dmp
Job "SYSTEM"."SYS_EXPORT_SCHEMA_01" successfully completed at 12:36

Scott의 객체가 어느 테이블스페잇에 존재하는지 확인 해 보자 :

Enter user-name: scott/scott

Connected to:
Oracle Database 10g Enterprise Edition Release 10.1.0.2.0 -
With the Partitioning, OLAP and Data Mining options

SQL> select owner, tablespace_name from dba_segments where owner='SCOTT';

OWNER TABLESPACE_NAME

------------------------------
SCOTT USERS
SCOTT USERS
SCOTT USERS
SCOTT USERS
SCOTT USERS
SCOTT USERS

이제 관련 테이블들을 삭제해 보자 :

SQL> drop table SALGRADE;

Table dropped.

SQL> drop table emp;

Table dropped.

SQL> drop table dept;

Table dropped.

SQL> drop table bonus;

Table dropped.

Import는 다음 명령으로 실행 시킨다.

impdp Scott/Scott DIRECTORY=dpump_dir1 DUMPFILE=newtbs.dmp
REMAP_TABLESPACE='USERS':'NEW_USERS'

sun1/home/prod/scmiller> impdp SYSTEM/manager DIRECTORY=dpump_dir1
DUMPFILE=newtbs.dmp REMAP_TABLESPACE='USERS':'NEW_USERS'

Import: Release 10.1.0.2.0 - Production on Tuesday, 23 December, 2003 14:50

Copyright (c) 2003, Oracle. All rights reserved.

Connected to: Oracle Database 10g Enterprise Edition Release 10.1.0.2.0 - Produn
With the Partitioning, OLAP and Data Mining options
Master table "SYSTEM"."SYS_IMPORT_FULL_01" successfully loaded/unloaded
Starting "SYSTEM"."SYS_IMPORT_FULL_01": SYSTEM/******** DIRECTORY=dpump_dir1 D
Processing object type SCHEMA_EXPORT/USER
Processing object type SCHEMA_EXPORT/SYSTEM_GRANT
Processing object type SCHEMA_EXPORT/ROLE_GRANT
Processing object type SCHEMA_EXPORT/DEFAULT_ROLE
Processing object type SCHEMA_EXPORT/SE_PRE_SCHEMA_PROCOBJACT/PROCACT_SCHEMA
Processing object type SCHEMA_EXPORT/TABLE/TABLE
Processing object type SCHEMA_EXPORT/TABLE/TABLE_DATA
. imported "NEWSCOTT"."DEPT" 5.656 KB 4 rows
. imported "NEWSCOTT"."EMP" 7.820 KB 14 rows
. imported "NEWSCOTT"."SALGRADE" 5.585 KB 5 rows
. imported "NEWSCOTT"."BONUS" 0 KB 0 rows
Processing object type SCHEMA_EXPORT/TABLE/INDEX/INDEX
Processing object type SCHEMA_EXPORT/TABLE/CONSTRAINT/CONSTRAINT
Processing object type SCHEMA_EXPORT/TABLE/INDEX/STATISTICS/INDEX_STATISTICS
Processing object type SCHEMA_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS
Processing object type SCHEMA_EXPORT/TABLE/CONSTRAINT/REF_CONSTRAINT
Job "SYSTEM"."SYS_IMPORT_FULL_01" successfully completed at 14:53

sun1/home/prod/scmiller> sqlplus

SQL*Plus: Release 10.1.0.2.0 - Production on Tue Dec 23 14:54:13 2003

Copyright (c) 1982, 2003, Oracle. All rights reserved.

sun1% sqlplus

SQL*Plus: Release 10.1.0.2.0 - Production on Tue Jan 13 12:53:36 2004

Copyright (c) 1982, 2003, Oracle. All rights reserved.

Enter user-name: / as sysdba

Connected to:
Oracle Database 10g Enterprise Edition Release 10.1.0.2.0 -
With the Partitioning, OLAP and Data Mining options

SQL> select owner, tablespace_name from dba_segments where owner='SCOTT';

OWNER TABLESPACE_NAME


------------------------------
SCOTT NEW_USERS
SCOTT NEW_USERS
SCOTT NEW_USERS
SCOTT NEW_USERS
SCOTT NEW_USERS
SCOTT NEW_USERS

6 rows selected.

=======================

여러개의 REMAP_TABLESPACE 파라미터를 지정할 수는 있으나, 두개 이상의 타겟 테이블스페이스에 대해
동일한 소스 테이블스페이스를 지정할 수 없다. 타겟 스키마는 타겟 테이블스페이스 내
충분한 quota를 부여 받은 상태이어야 한다.

주의해야 할 점은 REMAP_TABLESPACE 파라미터는 Data Pump Import에서만 유일하게 제공하는 테이블스페이스
remap 이법이라는 것이다. 이것은, Import 유틸리티 보다 깨끗하고 단순하게 작업을 수행할 수 있게 해
준다. Import 유틸리티에서는, 사용자의 default tablespace를 변경 시키기위해서는, export 및
사용자 drop, 사용자의 생성, 데이터 import와 같은 여러 단계의 작업을 수행 해야만 했었다. 이 방법에는
많은 제약 사항이 존제하는데 (테이블스페이스 지정과 관련 구문) 이것은 일부 DDL이 수행 실패하는
결과를 초래 하기도 한다.

그러나 Data Pump Import는 REMAP_TABLESPACE 파라미터를 제공하므로, 모든객체에 대해 DDL 구문에
어떤 테이블스페이스 지정 구문을 사용했던 상관 없이 안전하게 remap 시킬 수 있는 기능을 제공한다.

Reference Documents

Note:261085.1 Datapump: Remap Tablespace feature
Oracle Database Utilities 10g Release 1 (10.1)


출처 : http://kr.forums.oracle.com/forums/thread.jspa?messageID=1699010


Posted by 1010
02.Oracle/DataBase2009. 10. 20. 19:59
반응형

오라클9i에서 local 접속하던중 ora-12451 에러가 발생했다.

1.cmd -> services.msc
2. OracleOraHome92TNSListener (oracle 9i) 가 시작됐는지 확인.
혹은
3. listener.ora 에서 HOST가 제대로 되어 있는 확인한다

- listener.ora

  1. 오라클 서버에서 클라이어튼의 요청을 듣고, 클라이언트와의 통신 환경을 설정하는 파일

  2. 오라클 서버에 존재


$ORACLE_HOME/network/admin/listener.ora

-------------------------------------------------------------------

LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS_LIST =
        (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC0))
      )
      (ADDRESS_LIST =
        (ADDRESS = (PROTOCOL = TCP)(HOST = xxx)(PORT = 1521))
      )
    )
  )

SID_LIST_LISTENER =
  (SID_LIST =
    (SID_DESC =
      (SID_NAME = PLSExtProc)
      (ORACLE_HOME = C:\oracle\ora92)
      (PROGRAM = extproc)
    )
    (SID_DESC =
      (GLOBAL_DBNAME = local)
      (ORACLE_HOME = C:\oracle\ora92)
      (SID_NAME = local)
    )
  )

***리스너 관련 명령어***

c:\>lsnrctl start  리스너 시작하기

c:\>lsnrctl stop  리스너 정지하기

c:\>lsnrctl reload  리스너 재시작하기

c:\>lsnrctl status  리스너 상태보기

c:\>lsnrctl help  도움말



- tnsnames.ora

  1. 오라클 클라이언트 측에서 오라클 서버로 접속시 필요한 프로토콜, 포트번호, 서버주소  등을 설정해주는 파일

  2. 클라이언트에 위치

  3. 예제

      JJS =
          (DESCRIPTION =
                   (ADDRESS_LIST =
                          (ADDRESS = (PROTOCOL = TCP)(HOST = ip주소 )(PORT = 1521))
                    )
                   (CONNECT_DATA =
                          (SERVER = 서버 명)
                          (SERVICE_NAME = db명)
                    )
           )


p.s) listener.ora와 tnsnames.ora파일의 위치는 ORACLE_HOME/network/ADMIN/에 존재

출처 : http://ragew.tistory.com/category/DB노트

Posted by 1010
02.Oracle/DataBase2009. 10. 20. 19:58
반응형
select      b.username username,
              c.sid sid,
              c.owner object_owner,
              c.object object,
              b.lockwait,
              a.sql_text SQL
from        v$sqltext a, v$session b, v$access c
where     a.address=b.sql_address
and        a.hash_value=b.sql_hash_value
and        b.lockwait = 'WAIT'
and        b.sid = c.sid
and        c.owner != 'SYS'


출처 : http://ragew.tistory.com/3
Posted by 1010
02.Oracle/DataBase2009. 10. 20. 19:57
반응형

### Lock 확인 쿼리
SELECT do.object_name, do.owner, do.object_type,do.owner, vo.xidusn, vo.session_id,
vo.locked_mode
FROM v$locked_object vo , dba_objects do
WHERE vo.object_id = do.object_id ;

####  어떤 object에 어떤 lock이 걸렸는지 확인
SELECT  T1.object_name, DECODE(locked_mode, 2, 'ROW SHARE', 3, 'ROW EXCLUSIVE',  4, 'SHARE', 5, 'SHARE ROW EXCLUSIVE', 6, 'EXCLUSIVE', 'UNKNOWN') lock_mode
FROM  dba_objects T1, v$locked_object T2
WHERE T1.object_id = T2.object_id;

#### session 확인
select * from v$session where status = 'ACTIVE'

#### cursor 확인
v$open_cursor

#### 테이블의 lock 확인
SELECT A.SID, A.SERIAL#, B.TYPE, C.OBJECT_NAME
FROM V$SESSION A, V$LOCK B, DBA_OBJECTS C
WHERE A.SID=B.SID
AND B.ID1=C.OBJECT_ID
AND B.TYPE='TM'
AND C.OBJECT_NAME IN ('<테이블이름>');

/*******************************************************************************
* LOCK 관련
*******************************************************************************/
--V$LOCK 을 사용한 잠금 경합 모니터링
SELECT s.username, s.sid, s.serial#, s.logon_time,
  DECODE(l.type, 'TM', 'TABLE LOCK',
         'TX', 'ROW LOCK',
      NULL) "LOCK LEVEL",
  o.owner, o.object_name, o.object_type
FROM v$session s, v$lock l, dba_objects o
WHERE s.sid = l.sid
AND o.object_id = l.id1
AND s.username IS NOT NULL   

--락이 걸린 세션 자세히 알아보기
select a.sid, a.serial#,a.username,a.process,b.object_name,
decode(c.lmode,2,'RS',3,'RX',4,'S',5,'SRX',8,'X','NO') "TABLE LOCK",
decode (a.command,2,'INSERT',3,'SELECT',6,'UPDATE',7,'DELETE',12,'DROP TABLE',26,'LOCK TABLE','UNknown') "SQL",
decode(a.lockwait, NULL,'NO wait','Wait') "STATUS"
from v$session a,dba_objects b, v$lock c
where a.sid=c.sid and b.object_id=c.id1
and c.type='TM'

--락이 걸린 세션 간단히 알아보기
select a.sid, a.serial#, b.type, c.object_name, a.program, a.lockwait,
      a.logon_time, a.process, a.osuser, a.terminal
from v$session a, v$lock b, dba_objects c
where a.sid = b.sid
  and b.id1 = c.object_id
  and b.type = 'TM';

select a.sid, a.serial#, a.username, a.process, b.object_name
from v$session a , dba_objects b, v$lock c
where a.sid=c.sid and b.object_id = c.id1
and c.type = 'TM'

--락이 걸린 세션을 찾아 내어 세션을 죽이려고 해도 죽지 않는 경우
--아래 쿼리문으로 OS단의 PROCESS ID를 찾아내어 OS에서 죽인다
--kill -9 프로세스아이디
select substr(s.username,1,11) "ORACLE USER", p.pid "PROCESS ID",
s.sid "SESSION ID", s.serial#, osuser "OS USER",
p.spid "PROC SPID",s.process "SESS SPID", s.lockwait "LOCK WAIT"
from v$process p, v$session s, v$access a
where a.sid=s.sid and
p.addr=s.paddr and
s.username != 'SYS'

--위 쿼리문의 결과가 있다면 락이 걸린 세션이 있다는것이므로 아래의 쿼리문으로 세션을 죽인다
ALTER SYSTEM KILL SESSION '11,39061'

출처 : http://cocoroworld.com/blog/root/entry/오라클-락lock


출처 : http://cocoroworld.com/blog/root/entry/오라클-락lock

Posted by 1010
02.Oracle/DataBase2009. 10. 19. 16:02
반응형

*** 토드에서 save as를 통한 엑셀 저장시 한글깨짐 현상발생시 아래와 같은방법을 사용한다. ***

 


<토드 9.0.x>

방법 1. save as에서 Write Wide Strings 옵션에 체크한다.

방법 2. 토드 종료 후 C:\program Files\Quest Software\Toad for Oracle\User Files 폴더에 있는

         toad.ini파일 [SAVEAS]아래에 있는 cbXLSWideStrings=0 을 1로 수정하고 토드 재시작

 

사용자 삽입 이미지


<토드 8.6>

방법 1. 토드 종료 후 C:\program Files\Quest Software\Toad for Oracle\User Files 폴더에 있는

         toad.ini파일 [SAVEAS]아래에 있는 cbXLSWideStrings=1을 추가하고 재시작 한다.

Posted by 1010
02.Oracle/DataBase2009. 10. 19. 15:46
반응형

토드(toad)에서 한글이 깨져보일때


어떤 이는 레지스트리에서 변경을 하라고 하고.... 어떤 이는 환경변수에서 추가를 하라고 하고....
그래서 둘다 해보았더니.....

결국 환경변수의 추가로 해결이 되었다...

내 컴퓨터 - 속성 - 고급탭 - 환경변수 버튼 클릭

시스템 변수 란 - 새롤만들기 버튼 클릭

변수 : NLS_LANG
변수값 : KOREAN_KOREA.KO16MSWIN949

으로 설정을 하면 된다..

만약 안되면 레지스트리 변경을 시도해보면 될 듯 함.
regedit > HKEY_LOCAL_MACHINE > SOFTARE > ORACLE
문자열 : NLS_LANG
값 데이터 : KOREAN_KOREA.KO16KSC5601 혹은 KOREAN_KOREA.KO16MSWIN949
Posted by 1010
02.Oracle/DataBase2009. 9. 24. 19:48
반응형
alter session set global_names=true;


dblink tl seq 를 자동증가 할때  ***.nextval

ORA-04054: 데이터베이스 링크 'HSCPROD.NEXTVAL'가 존재하지 않습니다
                    
SELECT AAA_SEQ@hscprod.NEXTVAL
  FROM DUAL; (X)

SELECT AAA_SEQ.NEXTVAL@hscprod
  FROM DUAL (O)



SEQUENCE

 CREATE TABLE T1(ID NUMBER(4) CONSTRAINT T1_PK PRIMARY KEY, DATA VARCHAR2(30));


PK에 대해 SEQUENCE를 줄수 있다. 입력시에 아래처럼. 테이블에 시퀀스 하나씩!

 SQL> INSERT INTO T1 VALUES(T1_S.NEXTVAL, 'AA');

1 개의 행이 만들어졌습니다.

 SQL> CREATE SEQUENCE T1_S;

시퀀스가 생성되었습니다.

SQL> SELECT * FROM T1;

        ID DATA
---------- ------------------------------
         1 AA
         2 BB


 세션마다 CURRVAL은 다르지만, NEXTVAL은 같다. 세션에서 NEXTVAL을 사용하게 되면 하나씩 올라가게 된다..

 GAP이 생기면 시퀀스를 쓰지 말아야 하는거죠. 시퀀스대신 SELECT MAX(ID)+1 처럼 해야 된다. <- LOCK이 걸릴수 있기때문에 쓰지 마라.

 ISQL에서는 트랜젝션이 있으니까 상관없긴 하다.


  1  CREATE SEQUENCE DEPT_S
  2  INCREMENT BY 10
  3* START WITH 10
SQL> /

시퀀스가 생성되었습니다.

SQL> SELECT DEPT_S.NEXTVAL FROM DUAL;

   NEXTVAL
----------
        10

SQL> SELECT DEPT_S.NEXTVAL FROM DUAL;

   NEXTVAL
----------
        20


3,5,2,4,6,2,4,6 으로 증가하게 하려면?

 SQL>
  1  CREATE SEQUENCE TS
  2  INCREMENT BY 2
  3  START WITH 3
  4  MAXVALUE 6
  5  MINVALUE 2
  6* CYCLE NOCACHE

시퀀스가 생성되었습니다.

SQL> SELECT TS.NEXTVAL FROM EMP;

   NEXTVAL
----------
         3
         5
         2
         4
         6
         2
         4
         6
         2
         4
         6

   NEXTVAL
----------
         2
         4
         6

14 개의 행이 선택되었습니다.

Posted by 1010
02.Oracle/DataBase2009. 9. 3. 11:36
반응형
1. 설 명

☞ Bulletin no : 12036 참고

 
Oracle 8i Release2(8.1.6)에서는 데이터를 암호화하여 저장할 수 있는
향상된 기능(DES Encryption)을 제공 합니다
 
 
신용카드번호, 패스워드 등 보안이 필요한 데이터를 암호화된 형태로 저장하여
기존의 3rd Party Tool이나, Application Logic으로 구현하던 암호화 정책을
데이터베이스 차원에서 구현할 수 있도록 해줍니다.
 
 
 
DBMS_OBFUSCATION_TOOLKIT

암호화 기능을 이용하려면 DBMS_OBFUSCATION_TOOLKIT을 이용해야 합니다.
 
 
이 패키지는 4개의 프로시져로 이루어져 있습니다.

- VARCHAR2 타입을 Encrypt/Decrypt할 수 있는 2개의 프로시져

- RAW 타입을 Encrypt/Decrypt할 수 있는 2개의 프로시져
(다른 타입은 지원하지 않으므로 number인 경우는 to_char 이용)
 
 

DBMS_OBFUSCATION_TOOLKIT을 이용하기 위해서는 :

1) SYS 유저로 아래의 스크립트를 실행 시킵니다.

   @$ORACLE_HOME/rdbms/admin/dbmsobtk.sql
   @$ORACLE_HOME/rdbms/admin/prvtobtk.plb
   
2) 권한을 부여 합니다.

   SQL>GRANT execute ON dbms_obfuscation_toolkit TO public;


2. 패키지 실행하기



--> 패키지 선언부 생성

CREATE OR REPLACE PACKAGE CryptIT AS
   FUNCTION encrypt( Str VARCHAR2,  
                     hash VARCHAR2 ) RETURN VARCHAR2;

   FUNCTION decrypt( xCrypt VARCHAR2,
                     hash VARCHAR2 ) RETURN VARCHAR2;
END CryptIT;
/
 
 
 
--> 패키지 본체 생성

CREATE OR REPLACE PACKAGE BODY CryptIT AS
   crypted_string VARCHAR2(2000);
 
   FUNCTION encrypt( Str VARCHAR2,  
                     hash VARCHAR2 ) RETURN VARCHAR2 AS
   pieces_of_eight INTEGER := ((FLOOR(LENGTH(Str)/8 + .9)) * 8);
 
   BEGIN
 
      dbms_obfuscation_toolkit.DESEncrypt(
               input_string     => RPAD( Str, pieces_of_eight ),
               key_string       => RPAD(hash,8,’#’),
               encrypted_string => crypted_string );
      RETURN crypted_string;
   END;
 
   FUNCTION decrypt( xCrypt VARCHAR2,
                     hash VARCHAR2 ) RETURN VARCHAR2 AS
   BEGIN
      dbms_obfuscation_toolkit.DESDecrypt(
               input_string     => xCrypt,
               key_string       => RPAD(hash,8,’#’),
               decrypted_string => crypted_string );
      RETURN trim(crypted_string);
   END;
END CryptIT;
/

 



3. 실행 예제


1) Encrypt하여 데이터 입력

-- 테스트 테이블을 생성 합니다.

SQL>create table encrypt_table( id number, passwd varchar(20) );


 
-- 테스트 데이트럴 입력 합니다.
-- CryptIT.encrypt(비밀번호, 키값)

SQL>INSERT INTO encrypt_table VALUES( 1, CryptIT.encrypt(’1234’, ’storm’));
1 개의 행이 만들어졌습니다.

 
SQL>INSERT INTO encrypt_table VALUES( 2, CryptIT.encrypt(’5678’, ’oramaster’));
1 개의 행이 만들어졌습니다.

 
 
2) Decrypt하여 데이터 조회
 
--> Decrypt하지 않으면 암호화된 데이터와 비교되서 결과값이 출력되지 않습니다.
SQL> select id, passwd from encrypt_table where passwd = ’1234’;
 
선택된 레코드가 없습니다.
 
 
--> 저장장치에 Encrypt된 값으로 저장 됩니다.

SQL> col passwd format a60
SQL> select id, dump(passwd) passwd from encrypt_table;

         ID PASSWD
---------- -------------------------------------------------------------
         1 Typ=1 Len=8: 246,27,80,184,227,225,245,31
         2 Typ=1 Len=8: 175,231,213,125,85,223,46,133
 


--> Encrypt할 때 사용한 Key로만 Decrypt할 수 있습니다.
 
SQL>SELECT id, CryptIT.decrypt(passwd,’storm’) passwd
       FROM encrypt_table
       WHERE CryptIT.decrypt(passwd,’storm’) = ’1234’;
 
        ID PASSWD
---------- -----------
         1 1234
 
 
SQL>SELECT id, CryptIT.decrypt(passwd,’oramaster’) passwd
    FROM encrypt_table
    WHERE CryptIT.decrypt(passwd,’oramaster’) = ’5678’;
 
        ID PASSWD
---------- -----------
         2 5678
 
 
주의) Table에 접근 권한이 있는 다른 유저도 Key값을 알면 Decrypt할 수 있습니다.
 
 
 
4) 관련 ORA error number
 
ORA error 28231 "Invalid input to Obfuscation toolkit"
- input data, key값이 NULL일 경우 발생
 
ORA error 28232 "Invalid input size for Obfuscation toolkit"
- input data가 8 bytes 배수가 아닐 경우 발생
 
ORA error 28233 "Double encryption not supported by DESEncrypt in Obfuscation toolkit"
- encrypt data를 다시 encrypt경우 발생
 

관 련 자 료
===========
Oracle8i Supplied PL/SQL Packages Reference Release 2 (8.1.6)
 

  ================================================
    * 데이터베이스 정보공유 커뮤니티 oracleclub.com
    * 강좌 작성자 : 김정식 (oramaster _at_ naver.com)
  ================================================
※ oracleclub 강좌를 다른 웹 페이지에 게재할 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^^
※ oracleclub 강좌는 개인의 학습용으로만 사용 할 수 있습니다. 학원 홍보용이나 수익을 얻기 위한 용도로
    사용을 하시면 안됩니다. ^^


출처 : http://www.oracleclub.com/lectureview.action
Posted by 1010
02.Oracle/DataBase2009. 8. 12. 15:59
반응형
출처 : http://javaservice.net/
--테이블별 현황보기
create or replace
procedure show_space
( p_segname in varchar2,
p_owner in varchar2 default user,
p_type in varchar2 default 'TABLE' )
as
l_free_blks number;
 
l_total_blocks number;
l_total_bytes number;
l_unused_blocks number;
l_unused_bytes number;
l_LastUsedExtFileId number;
l_LastUsedExtBlockId number;
l_LAST_USED_BLOCK number;
procedure p( p_label in varchar2, p_num in number )
is
begin
dbms_output.put_line( rpad(p_label,40,'.') || p_num );
end;
begin
dbms_space.free_blocks
( segment_owner => p_owner,
segment_name => p_segname,
segment_type => p_type,
freelist_group_id => 0,
free_blks => l_free_blks );
 
dbms_space.unused_space
( segment_owner => p_owner,
segment_name => p_segname,
segment_type => p_type,
total_blocks => l_total_blocks,
total_bytes => l_total_bytes,
unused_blocks => l_unused_blocks,
unused_bytes => l_unused_bytes,
LAST_USED_EXTENT_FILE_ID => l_LastUsedExtFileId,
LAST_USED_EXTENT_BLOCK_ID => l_LastUsedExtBlockId,
LAST_USED_BLOCK => l_LAST_USED_BLOCK );
 
p( 'Free Blocks', l_free_blks );
p( 'Total Blocks', l_total_blocks );
p( 'Total Bytes', l_total_bytes );
p( 'Unused Blocks', l_unused_blocks );
p( 'Unused Bytes', l_unused_bytes );
p( 'Last Used Ext FileId', l_LastUsedExtFileId );
p( 'Last Used Ext BlockId', l_LastUsedExtBlockId );
p( 'Last Used Block', l_LAST_USED_BLOCK );
end;
/
set serveroutput on
exec show_space( 'EMP' );
 
--테이블스페이스 현황보기
column dummy noprint
column pct_used format 999.9 heading "%|Used"
column name format a16 heading "Tablespace Name"
column Kbytes format 999,999,999 heading "KBytes"
column used format 999,999,999 heading "Used"
column free format 999,999,999 heading "Free"
column largest format 999,999,999 heading "Largest"
break on report
compute sum of kbytes on report
compute sum of free on report
compute sum of used on report
 
select nvl(b.tablespace_name,
nvl(a.tablespace_name,'UNKOWN')) name,
kbytes_alloc kbytes,
kbytes_alloc-nvl(kbytes_free,0) used,
nvl(kbytes_free,0) free,
((kbytes_alloc-nvl(kbytes_free,0))/
kbytes_alloc)*100 pct_used,
nvl(largest,0) largest
from ( select sum(bytes)/1024 Kbytes_free,
max(bytes)/1024 largest,
tablespace_name
from sys.dba_free_space
group by tablespace_name ) a,
( select sum(bytes)/1024 Kbytes_alloc,
tablespace_name
from sys.dba_data_files
group by tablespace_name )b
where a.tablespace_name (+) = b.tablespace_name
order by 1
/
 
--테이블스페이스 현황보기(덤으로)
SELECT
sysdate inst_date ,
ddf.tablespace_name tspace ,
ROUND(fst.FRAG_INDEX,2) fragindex ,
allspc.KB totalaloc ,
(ddf.fretot - fst.total_free ) /1024 totalused ,
fst.total_free /1024 totalfree ,
ROUND((fst.total_free /ddf.fretot),2) * 100 frepct ,
fst.max_hole /1024 maxdiv ,
ROUND((fst.avg_hole /1024),2) avgdiv ,
fst.holes num_of_div
FROM dual,
(SELECT
tablespace_name tablespace_name ,
SUM(bytes) fretot
FROM dba_data_files
WHERE tablespace_name != 'TEMP'
group by tablespace_name) ddf,
(
SELECT tablespace_name tablespace_name,
SQRT(MAX(BLOCKS)/SUM(BLOCKS))*(100/SQRT(SQRT(COUNT(BLOCKS)) ))
FRAG_INDEX,
SUM(bytes) total_free,
MAX(bytes) max_hole,
AVG(bytes) avg_hole,
COUNT(*) holes
FROM dba_free_space
WHERE tablespace_name != 'TEMP'
GROUP BY tablespace_name
) fst,
(select table_space tablespace_name , sum(x) KB from
(select tablespace_name table_space,sum(BYTES/1024) x from
dba_data_files
where maxbytes=0 and
tablespace_name != 'TEMP'
group by tablespace_name
union all
select tablespace_name table_space,sum(MAXBYTES/1024) x from
dba_data_files
where tablespace_name != 'TEMP'
group by tablespace_name
)group by table_space) allspc
WHERE ddf.tablespace_name = fst.tablespace_name(+)
and ddf.tablespace_name = allspc.tablespace_name(+);


출처 : http://blog.empas.com/jb0077/21023496
Posted by 1010
02.Oracle/DataBase2009. 8. 12. 15:58
반응형
오라클 실행계획(explan table) 보기.

작성자: 안창선(kabin@kldp.org)

오라클을 사용하면서 느낀것이 plan을 뜨는게 인포믹스보다 번거롭게 느껴지더군요.
그래서그런지 사용하는분을 별로 보지 못했습니다. 이제 아래 내용을 따라 하시면..
아주 쉽게 plan을 떠보고 SQL문을 튜닝하실 수 있을겁니다.

오라클은 실행계획이라는 것을 확인하여 성능을 측정할 수 있습니다.
엄밀히 말해 성능을 측정하는게 아니라 SQL리 인덱스를 적절히 쓰고 있는지
아니면 인덱스가 무시된체 full table scan을 하여 성능을 떨어뜨리게 되는지등을
확인하는 것입니다.(맞나?)

1. 우선 실행계획을 측정 하려면 실행계획을 확인한 자료를 오라클 DB에 저장할 수
있도록 실행계획 테이블을 만들어 줘야 합니다. 실행계획 테이블의 이름은 어떠한
이름을 가지고 있더라도 상관은 없지만 아래의 테이블 필드를 가지고 있어야
합니다. 따라서 실행계획을 확인하기 위한 첫 작업은 실행계획 테이블을 만드는
것이겠지요. 우리는 디폴트 이름은 PLAN_TABLE이라고 이름을 지읍시다.

create table PLAN_TABLE (
statement_id varchar2(30),
timestamp date,
remarks varchar2(80),
operation varchar2(30),
options varchar2(30),
object_node varchar2(128),
object_owner varchar2(30),
object_name varchar2(30),
object_instance numeric,
object_type varchar2(30),
optimizer varchar2(255),
search_columns numeric,
id numeric,
parent_id numeric,
position numeric,
other long);
create unique index PLAN_TABLE_INDEX
on PLAN_TABLE ( statement_id, id)

2. 자 이제 실행계획 자료를 저장할 테이블을 만들었으니 이제 특정 SQL의
실행계획을 확인해 봅시다.

delete plan_table
/
EXPLAIN PLAN SET STATEMENT_ID = 'plan1' --> 해당실행문의 제목
INTO PLAN_TABLE
FOR
SELECT *
FROM test_table a
WHERE a.test like 'hi'||'%'
/

즉 위의 문장은 일단 실행계획테이블(plan_table)의 자료를 일단 모두 지운다음에.
plan1 ID로 문장을 지정하고 아래에 나오는 SQL문장의 결과를 PLAN_TABLE에
저장 하라는 명령입니다.

3. 이제 실행계획의 결과값을 봅시다.

결과값은 실행계획 테이블에 들어가 있습니다. 결과값을 보려면 아래의 SQL을
실행시켜 보십시오. 단 STATEMENT_ID와 PLAN_TABLE은 여러분이 정의한 것을
입력하셔야겠지요.

SELECT lpad(operation,length(operation)+2*(level-1)) ||
decode(id,0,'CostEstimate:'||decode(position,'0','N/A',position),null)||
''||options||
decode(object_name,null,null,':')||rpad(object_owner,length(object_name)+1,',')||
object_name||
decode(object_type,'unique','(U)','NON-UNIQUE',
'(NU)',null)||decode(object_instance,null,null,'('||object_instance||')')
FROM PLAN_TABLE
START with ID = 0 AND STATEMENT_ID = 'plan1'
CONNECT by prior ID = PARENT_ID and STATEMENT_ID = 'plan1'
/

4. 위의 결과값

예를 들어 이런 것이 나올 수 있습니다.

LPAD(OPERATION,LENGTH(OPERATION)+2*(LEVEL-1))||DECODE(ID,0,'COSTESTIMATE:'||DECO
--------------------------------------------------------------------------------
SELECT STATEMENTCostEstimate:
TABLE ACCESSBY INDEX ROWID:HDMF,,,,,,,,W5_CARVAL_T(1)
INDEXRANGE SCAN:HDMF,,,,,,,,,,,,,,,,,,W5_CARVAL_T_CNAME_IDX(NU)

여기 위를 보면 accessby index 어쩌구 나오지요? 즉 인덱스를 사용하고 있다는
겁니다.
그리고 그 인덱스는 W5_CARVAL_T_CNAME_IDX을 쓰고 있다고 하는 것이구요.

만약 내용이

LPAD(OPERATION,LENGTH(OPERATION)+2*(LEVEL-1))||DECODE(ID,0,'COSTESTIMATE:'||DECO
--------------------------------------------------------------------------------
SELECT STATEMENTCostEstimate:
TABLE ACCESSFULL:HDMF,,,,,,,,W5_CARVAL_T(1)

이런 식으로 나오면 인덱스를 전혀 사용하지 못하고 테이블을 일일이 뒤진다는
거지요.
위에 보면 accessfull이라는게 있지요. 즉 테이블을 전체 검색하고 있다는 뜻입니다.
 
Posted by 1010
02.Oracle/DataBase2009. 8. 12. 15:19
반응형

10.명령어


[2008.06.02] 오라클 내장함수#


숫자 함수(number function)#


ABS ACOS ASIN ATAN
ATAN2 BITAND CEIL COS
COSH EXP FLOOR LN
LOG MOD POWER ROUND(number)
SIGN SIN SINH SQRT
TAN TANH TRUNC(number) WIDTH_BUCKET


① ROUND(45.926, 2) --> 45.93 : 소수점 두자리수까지 보여주면서 반올림한다.
② TRUNC(45.926, 2) --> 45.92 : 소수점 두자리까지만 보여주고 나머지는 버린다.
③ MOD(1600,300) --> 100 : 1600을 300으로 나누고 나머지를 리턴한다.
* ROUND예제(WHOLE NUMBER:정수)
SELECT ROUND(45.923,2), ROUND(45.923,0), ROUND(45.923,-1) FROM DUAL
==> 45.92 46 50

* TRUNC예제
SELECT TRUNC(45.923,2), TRUNC(45.923), TRUNC(45.923,-1) FROM DUAL
==> 45.92 45(n이 생략된면 일의 자리까지 남기고 버린다.) 40

* SYSTEM 날짜를 갖고 오는 방법.
SELECT sysdate FROM dual


/** 함수 - Number Function **/
--무조건 올림
SELECT CEIL(13.11) FROM DUAL;
SELECT CEIL(13.001) FROM DUAL;

--나머지 구함
SELECT MOD(23, 5) FROM DUAL;
SELECT MOD(57, 145) FROM DUAL;

-- 제곱승
SELECT POWER(3, 2), POWER(3, -2) FROM DUAL;
SELECT POWER(2, 10) FROM DUAL;

--자릿수 지정
SELECT ROUND(345.123, 0) FROM DUAL;
SELECT ROUND(345.123, 2), ROUND(345.123, -1) FROM DUAL;

--지정된 자리까지 잘라내기
SELECT TRUNC(345.123, 1), TRUNC(345.123, 0), TRUNC(345.123, -1) FROM DUAL;
SELECT TRUNC( 345.123 + 0.09, 1 ) FROM DUAL;
SELECT TRUNC( 345.123 + 0.9, 0 ) FROM DUAL;
SELECT TRUNC( 345.123 + 9, -1 ) FROM DUAL;

SELECT SIGN(5.989), SIGN(0), SIGN(-999.098) FROM DUAL;


문자 함수(character function)#


CHR CONCAT INITCAP LOWER
LPAD LTRIM NLS_INITCAP NLS_LOWER
NLSSORT NLS_UPPER REPLACE RPAD
RTRIM SOUNDEX SUBSTR TRANSLATE
TREAT TRIM UPPER ASCII
INSTR LENGTH, LENGTHB, LENGTHC, LENGTH2, LENGTH4

select ascii('B') from dual;

=> 66


①LOWER( column|expression )

LOWER('String') --> string : 소문자로 변환

②UPPER( column|expression )
UPPER('String') --> STRING : 대문자로 변환

③INITCAP( column|expression )
INITCAP('string') --> String : 첫글자만 대문자이고 나머지글자는 소문자로 변환


④CONCAT( column1|expression1 ,column2|expression2 )
CONCAT('Good','String') --> GoodString : ||와 같은 역할을 한다.

⑤SUBSTR(column|expression, m [,n]) : m값이 음수면 문자값의 끝부터..)
SUBSTR('String',1,3) --> Str : 1번째부터 3개의 문자를 리턴한다.

⑥LENGTH( column|expression )
LENGTH('String') --> 6 : 문자열의 길이를 리턴한다.

⑦INSTR( column|expression, )
INSTR('String','r') --> 3 : 문자열에 'r'이 몇번째 위치하고 있나를 리턴한다.

⑧LPAD( column|expression,n,'string' ) : n 은 전체 길이
LPAD('String',10,'*') --> ****String
: 10자리수중에 모자란 자리수를 '*'로 왼쪽에 채운다.(문자,숫자 가능!!!)

⑨ RPAD('String',10,'*') --> String****
: 10자리수중에 모자란 자리수를 '*'로 오른쪽에 채운다.(문자,숫자 가능!!!)

⑩ LTRIM(' String') --> 'String' : 문자열의 왼쪽 공백을 버린다.


⑪ RTRIM('String ') --> 'String' : 문자령의 오른쪽 공백을 버린다.
* TRIM(leading/tailing/both, trim_character FROM trim_source )

TRIM( 'S' FROM 'SSMITH') --> MITH


/** 함수 - Character Function **/
--특정Character의 아스키값 구하기
SELECT CHR(65) "CHR", ASCII('A') "ASCII" FROM DUAL;
SELECT ASCII( CHR(65) ) FROM DUAL;

SELECT LOWER('My name is LKM') "LOWER", UPPER('My name is LKM') "UPPER" FROM DUAL;

SELECT LPAD('LKM', 10, '*') "LPAD", RPAD('LKM', 10, '*') "RPAD" FROM DUAL;
SELECT LPAD('1234567890', 20, '+') || RPAD('1234567890', 20, '^') "12345678901234567890"
FROM DUAL;
SELECT LPAD('1,234,567', 30, ' ') "LPAD사용으로 30자리 맞춤",
'1,234,567' "단순문자 사용",
1234567 "단순숫자 사용"
FROM DUAL;

SELECT LTRIM(' AAA ') "LTRIM", RTRIM(' AAA ') "RTRIM" FROM DUAL;
SELECT LTRIM( RTRIM( ' A A A ' ) ) "TRIM" FROM DUAL;

SELECT REPLACE('ORACLE', 'A', 'BBB') "REPLACE" FROM DUAL;
SELECT EMP_NAME, REPLACE(EMP_NAME, '이', '박') "이->박"
FROM PERSONNEL
WHERE EMP_NAME LIKE '이%';

SELECT SUBSTR('ORACLE PROJECT', 1, 3) SUBSTR1,
SUBSTR('ORACLE PROJECT', 4, 5) SUBSTR2,
SUBSTR('ORACLE PROJECT', 10) SUBSTR3 FROM DUAL ;
SELECT SUBSTRB('ORACLE PROJECT', 1, 3) SUBSTRB1,
SUBSTRB('ORACLE PROJECT', 4, 5) SUBSTRB2,
SUBSTRB('ORACLE PROJECT', 10) SUBSTRB3 FROM DUAL ;
SELECT SUBSTR('오라클 PROJECT', 1, 3) SUBSTR1,
SUBSTR('오라클 PROJECT', 4, 5) SUBSTR2,
SUBSTR('오라클 PROJECT', 10) SUBSTR3 FROM DUAL ;
SELECT SUBSTRB('오라클 PROJECT', 1, 3) SUBSTRB1,
SUBSTRB('오라클 PROJECT', 4, 5) SUBSTRB2,
SUBSTRB('오라클 PROJECT', 10) SUBSTRB3 FROM DUAL ;

SELECT LENGTH ('ORACLE PROJECT') "LENGTH",
LENGTHB('ORACLE PROJECT') "LENGTHB",
FROM DUAL;
SELECT EMPNO, LENGTH(EMPNO), LENGTHB(EMPNO),
EMP_NAME, LENGTH(EMP_NAME), LENGTHB(EMP_NAME)
FROM PERSONNEL
WHERE EMPNO > '98102';
SELECT HOBBY, LENGTH(HOBBY), LENGTHB(HOBBY)
FROM PERSONNEL
WHERE EMPNO > '98102';

SELECT INSTR ('ORACLE PROJECT', 'R', 1, 1) INSTR1,
INSTR ('ORACLE PROJECT', 'R', 1, 2) INSTR2,
INSTR ('ORACLE PROJECT', 'R', 1, 3) INSTR3
FROM DUAL;
SELECT INSTR ('CORPORATE FLOOR','OR', 3, 2) INSTR,
INSTRB ('CORPORATE FLOOR','OR', 3, 2) INSTRB
FROM DUAL;
SELECT HOBBY,
INSTR (HOBBY, ')', 1, 1) INSTR,
INSTRB(HOBBY, ')', 1, 1) INSTRB
FROM PERSONNEL

WHERE EMPNO > '98102';



날짜와 날짜 처리함수(date, datetime function)#


ADD_MONTHS CURRENT_DATE CURRENT_TIMESTAMP DBTIMEZONE
EXTRACT(datetime) FROM_TZ LAST_DAY LOCALTIMESTAMP
MONTHS_BETWEEN NEW_TIME NEXT_DAY NUMTODSINTERVAL
NUMTOYMINTERVAL ROUND(date) SESSIONTIMEZONE SYS_EXTRACT_UTC
SYSDATE SYSTIMESTAMP TO_DSINTERVAL TO_TIMESTAMP
TO_TIMESTAMP_TZ TO_YMINTERVAL TRUNC(date) TZ_OFFS


date + number : date에 number만큼 후의 날자를 보여준다.
date - number : date에 number만큼 전의 날자를 보여준다.
date1 - date2 : date1에서 date2 까지의 총 일수를 보여준다.( date1+date2는 X )
date1 + 숫자/24 : date1에서 시간을 더해 날짜를 보여준다.


NUMTODSINTERVAL

NUMTODSINTERVAL(n,'char_expr') 함수는 n을 interval day to second로 변환하여 출력한다.
 char_expr은 다음 중의 하나이다.
  ‘DAY’
  ‘HOUR’
  ‘MINUTE’
  ‘SECOND’


MONTHS_BETWEEN('01-SEP-95','11-JAN-94') --> 19.6774194
; 두날짜 사이의 달수를 보여준다.

ADD_MONTHS('11-JAN-94', 6) --> 11-JUL-94
; 날짜에 6개월을 더한 날자를 보여준다.

NEXT_DAY('01-SEP-95','FRIDAY') --> '08-SEP-95'
; 해당일 다음에 오는 FRIDAY의 일자를 보여준다.
('SUNDAY'는 1, 'MONDAY'는 2...이런식으로 숫자를 써줘도 된다.)

LAST_DAY('01-SEP-95') --> '30-SEP-95'
; 해당월의 마지막날자를 보여준다.

ROUND('25-JUL-95','MONTH')--> 01-AUG-95 ROUND('25-JUL-95','YEAR')--> 01-JAN-96
TRUNC('25-JUL-95','MONTH') --> 01-JUL-95 TRUNC('25-JUL-95','YEAR') --> 01-JAN-95


/** 함수 - Date Function **/
SELECT SYSDATE FROM DUAL;
SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS') "SYSDATE" FROM DUAL;

SELECT LAST_DAY(SYSDATE) FROM DUAL;
SELECT TO_CHAR(LAST_DAY(SYSDATE), 'YYYY-MM-DD HH24:MI:SS') "LAST_DAY" FROM DUAL;

SELECT MONTHS_BETWEEN( '2002/01/13', '2002/05/13' ) "MONTHS_BETWEEN (-)",
MONTHS_BETWEEN( '2002/01/13', '2001/11/13' ) "MONTHS_BETWEEN (+)"
FROM DUAL ;
SELECT MONTHS_BETWEEN( '2002/01/13', '2002/01/30' ) "MONTHS_BETWEEN (-)",
MONTHS_BETWEEN( '2002/01/13', '2002/01/01' ) "MONTHS_BETWEEN (+)"
FROM DUAL ;

SELECT ADD_MONTHS(SYSDATE, 1) "ADD_MONTHS (+)",
ADD_MONTHS(SYSDATE, -1) "ADD_MONTHS (-)"
FROM DUAL ;

ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD';
SELECT ADD_MONTHS( '2002/02/28', 12 ) "1년후",
ADD_MONTHS( '2002/02/28', 24 ) "2년후",
ADD_MONTHS( '2002/02/28', 36 ) "3년후"
FROM DUAL ;

SELECT SYSDATE,
NEXT_DAY(SYSDATE, '일요일') "NEXT_DAY 1",
NEXT_DAY(SYSDATE, 1 ) "NEXT_DAY 2"
FROM DUAL;
SELECT SYSDATE,
NEXT_DAY(SYSDATE, '수요일') "NEXT_DAY 1",
NEXT_DAY(SYSDATE, 4 ) "NEXT_DAY 2"
FROM DUAL;


데이터 형변환 함수(conversion function)#


ASCIISTR BIN_TO_NUM CAST CHARTOROWID
COMPOSE CONVERT DECOMPOSE HEXTORAW
NUMTODSINTERVAL NUMTOYMINTERVAL RAWTOHEX RAWTONHEX
ROWIDTOCHAR ROWIDTONCHAR TO_CHAR(character) TO_CHAR(datetime)
TO_CHAR(number) TO_CLOB TO_DATE TO_DSINTERVAL
TO_LOB TO_MULTI_BYTE TO_NCHAR(character) TO_NCHAR(datetime)
TO_NCHAR(number) TO_NCLOB TO_NUMBER TO_SINGLE_BYTE
TO_YMINTERVAL TRANSLATE ... USING UNISTR


nlsparams : 십진수, 그룹구분자, 지역 통화 기호, 국제 통화 기호

TO_CHAR(date,['format'],[nlsparams]) : date를 format에 맞게 문자열로 변환한다.

- Date Format Elements
YYYY --> 1999 (년출력) , YEAR --> nineteen ninety-nine (년출력)
MM --> 12 (월출력) , MONTH --> DECEMBER (월출력), MON --> DEC
D --> 요일을 숫자로 리턴한다.(일요일은 1, 월요일은 2...)
DD --> 07 (달의 일출력)
DDD --> 200 (연의 일출력)그 해의 총 몇 일째인가를 리턴한다.
DAY --> MONDAY (요일출력) DY-->MON
CC --> 20 (몇 세기인지를 보여준다.)
WW --> 그 해의 몇 번째 주인가를 리턴한다.
W --> 그 달의 몇 번째 주인가를 리턴한다.

=>  흔히 사용하는 위의 형태는 일상 생활에서 사용되는 몇주 개념적용이 아닌


7일 단위로 끊은 주 개념입니다.


예를 들어 2005년 1월 2일의 경우 일요일로서 일상 생활에서는 2005년의 2주차 입니다.


하지만 to_char('20050102','ww') 의 경우 '2005'년도의 2일째 이기에 1주 로 계산 합니다.


(2006년의 경우 '20060101'이 정확히 일요일이기 때문에 to_char(sysdate,'ww')의 값을 오해 할 수 있습니다. 2005년 또는 2007년 경우를 확인 해 보시면 이해에 도움이 될 것입니다.)



* Element들을 소문자로 쓰면 소문자로 나오고 대문자로 쓰면 대문자로 출력된다.
HH or HH12 or HH24 / MI(0-59분) / SS(0-59초)


* 문자열은 " " 묶어 추가한다 DD " of " MONTH --> 12 of DECEMBER

*숫자 접미어는 숫자를 문자로 표기. TH(4->4TH)/ SP(4->FOUR)/ SPTH or THSP(4->FOURTH)

ddspth : 14-> fothteenth

* / . , : 구두점은 결과에 그대로 출력한다. * 공백, 선행제로를 제거하는 fm요소가 있다.

TO_CHAR(number,'format',[nlsparams]) : number를 format에 맞게 문자열로 변환한다.

- Number Format Elements
9 : 999,999 --> 1,234 $: 부동 달러 기호 $99999 -> $1234
0 : 099999 --> 001234 99.999EEEE -> 1.234E+03 B: 0값을 공백으로
L : L99,999 --> FF1,234 (NLS_CURRENCY에 설정되어있는 값이 L로 보여진다.)

TO_NUMBER(char,['format'],[nlsparams]) : 숫자형태의 문자열을 숫자로 변한한다.
TO_DATE(char,['format'],[nlsparams]):날자형태의 문자열을 format에 맞게 날자형식으로 변환 한다.


/** 함수 - Conversion Function **/
SELECT TO_CHAR(1234567.891) "TO_CHAR1",
TO_CHAR(1234567.891, '999') "TO_CHAR2",
TO_CHAR(1234567.891, '9,999,999') "TO_CHAR3",
TO_CHAR(1234567.891, '0.0000') "TO_CHAR5",
TO_CHAR(1234567.891, '9,999,999.0000') "TO_CHAR6",
TO_CHAR(123, '9,999.00') "TO_CHAR7",
TO_CHAR(123, '9,999.99') "TO_CHAR8"
FROM DUAL ;
SELECT TO_CHAR(1234567.891, '9G999G999') "TO_CHAR3",
TO_CHAR(1234567.891, '0D0000') "TO_CHAR5",
TO_CHAR(1234567.891, '9G999G999D0000') "TO_CHAR6",
TO_CHAR(123, '9G999D00') "TO_CHAR7",
TO_CHAR(123, '9G999D99') "TO_CHAR8"
FROM DUAL ;

SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD') "TO_CHAR1",
TO_CHAR(SYSDATE, 'YYYY/MM') "TO_CHAR2",
TO_CHAR(SYSDATE, 'YYYY') "TO_CHAR3",
TO_CHAR(SYSDATE, 'DD') "TO_CHAR4",
TO_CHAR(SYSDATE, 'DAY') "TO_CHAR5",
TO_CHAR(SYSDATE, 'YYYY/MM/DD HH24:MI:SS') "TO_CHAR6",
TO_CHAR(TO_DATE('20020101','YYYYMMDD'), 'YYYY-MM-DD') "TO_CHAR7",
TO_CHAR(TO_DATE('20020101','YYYYMMDD'), 'YYYYMMDD HHMISS') "TO_CHAR8"
FROM DUAL ;

SELECT TO_NUMBER('123456.9') "TO_NUMBER1",
TO_NUMBER('1234567') "TO_NUMBER2"
FROM DUAL ;
SELECT TO_NUMBER('123,456.9', '999,999.9') "TO_NUMBER1",
TO_NUMBER('1,234,567', '9G999G999') "TO_NUMBER2"
FROM DUAL ;

ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS';
SELECT TO_DATE('20020824') "TO_DATE1",
TO_DATE('2002-08-24') "TO_DATE2",
TO_DATE('200208') "TO_DATE3"
FROM DUAL ;
SELECT TO_DATE('20020824', 'YYYYMMDD') "TO_DATE1",
TO_DATE('2002-08-24', 'YYYY-MM-DD') "TO_DATE2",
TO_DATE('200208', 'YYYYMM') "TO_DATE3"
FROM DUAL ;
SELECT TO_DATE('2002/08/24 08:14:06', 'YYYY/MM/DD HH24:MI:SS') "TO_DATE1",
TO_DATE('2002/08/24 08:14:06 오후', 'YYYY/MM/DD HH:MI:SS AM') "TO_DATE2"
FROM DUAL ;


기타함수(miscellaneous single row function)#


BFILENAME COALESCE DECODE DEPTH
DUMP EMPTY_BLOB EXISTSNODE EXTRACT(XML)
EMPTY_CLOB
EXTRACTVALUE GREATEST LEAST NLS_CHARSET_DECL_LEN
NLS_CHARSET_ID NLS_CHARSET_NAME NULLIF NVL
NVL2 PATH SYS_CONNECT_BY_PATH SYS_CONTEXT
SYS_DBURIGEN SYS_EXTRACT_UTC SYS_GUID SYS_TYPEID
SYS_XMLAGG SYS_XMLGEN UID UPDATEXML
USER USERENV VSIZE XMLAGG
XMLCOLATTVAL XMLCONCAT XMLFOREST XMLSEQUENCE
XMLTRANSFORM XMLELEMENT CASE


NVL Funcion : 값이 null일 때 설정값을 보여준다.
NVL(number_column, 0) : null일 때 0을 보여준다.
NVL(date_column, '01-JAN-95') : null일 때 '01-JAN-95'를 보여준다.
NVL(character_column, 'Empty') : null일 때 'Empty'를 보여준다.
* column Type과 표현식의 type이 반드시 일치해야 한다.

DECODE Function : CASE or IF-THEN-ELSE 형식과 비슷하다.
*DECODE(col/expression, search1, result1 [,search2,result2,…] [,default])
F1 (F2 (F3 (col,arg1),arg2),arg3)

이중 Decode나 Nvl 그리고, To_데이터형은 너무나도 많이 쓰여서 잘 안 까먹지만....
숫자나 문자관련 함수 잘 안쓰면 찾기가 너무 힘들다는..... '그 뭐시기냐 문자열의 위치 찾아내는거
그 함수 뭐냐?' 라면 '그게 뭔데?'라는 반문이-_- 차라리 instr이 뭐하는거지가 더 쉬운 질문이다-_-
대전 있을때 자료전환건이 있어서... 처리를 하려고 보니 특정칼럼 하나에 잘 쓰이지 않는
두개의 필드값을 탭구분자로 나눠서 때려넣어논 꼴을 본적이 있다. instr, chr, replace로 간단히 해결가능할걸 instr과 chr를 잘 몰라 통째로 엑셀로 받아 수작업을 했다라는....

/** 함수 - ETC **/
SELECT EMPNO, EMP_NAME, HOBBY 취미, WELL 특기
FROM PERSONNEL
WHERE EMPNO BETWEEN '98001' AND '98005';
SELECT EMPNO, EMP_NAME, HOBBY 취미, NVL(WELL, '(없다)') 특기
FROM PERSONNEL
WHERE EMPNO BETWEEN '98001' AND '98005';

SELECT DECODE( '나', '나', '맞다', '아니다' ) "나가 나면 맞다, 아니면 아니다"
FROM DUAL ;
SELECT DECODE( '나', '대명', '아니다',
'너' , '아니다',
'그' , '아니다',
'나' , '맞다',
'모르겠다' ) FROM DUAL ;
SELECT EMPNO,
EMP_NAME,
DECODE (HT_CODE, '1', '현재원', '2', '휴직', '퇴사') HT_CODE
FROM PERSONNEL
WHERE EMPNO BETWEEN '98071' AND '98080';

SELECT GREATEST (132, 33, 45, 90, 60.77) GREATEST,
LEAST (132, 33, 45, 90, 60.77) LEAST
FROM DUAL;
SELECT GREATEST ('이공명', '이대명', '최수미') GREATEST,
LEAST ('이공명', '이대명', '최수미') LEAST
FROM DUAL;

SELECT USERENV('LANGUAGE') "LANGUAGE",
USERENV('TERMINAL') "TERMINAL",
USERENV('SESSIONID') "SESSIONID"
FROM DUAL;

SELECT UID, USER FROM DUAL;


그룹함수 - 집계(Aggregate) 함수#


AVG CORR COUNT COVAR_POP
COVAR_SAMP CUME_DIST DENSE_RANK FIRST
GROUP_ID GROUPING GROUPING_ID LAST
MAX MIN PERCENTILE_CONT PERCENTILE_DISC
PERCENT_RANK RANK REGR function STDDEV
STDDEV_POP STDDEV_SAMP SUM VAR_POP
VAR_SAMP VARIANCE GROUPING SETS


/** 함수 - Group Function **/
SELECT AVG(HEIGHT), AVG(WEIGHT) FROM PERSONNEL;

SELECT MAX(EMPNO), MAX(EMP_NAME), MIN(EMPNO), MIN(EMP_NAME) FROM PERSONNEL;
SELECT MAX(HEIGHT), MIN(HEIGHT) FROM PERSONNEL;

SELECT SUM(WEIGHT) FROM PERSONNEL;

SELECT COUNT(*), COUNT(EMPNO), COUNT(JIKCH_CODE) FROM PERSONNEL;


그룹함수 -  분석(Analytic) 함수#


AVG CORR COUNT COVAR_POP
COVAR_SAMP CUME_DIST DENSE_RANK FIRST
FIRST_VALUE LAG LAST LAST_VALUE
LEAD MAX MIN NTILE
PERCENT_RANK PERCENTILE_CONT PERCENTILE_DISC RANK
RATIO_TO_REPORT REGR_(linear regression) function ROW_NUMBER STDDEV
STDDEV_POP STDDEV_SAMP SUM VAR_POP
VAR_SAMP VARIANCE TOP_N 분석


윈도우(windowing) 분석 함수#

윈도우 분석함수는 전체 결과 집합 중에서 연속선상에 있는 부분 집합을 대상으로 적용하는 함수의 집합을 말한다.
윈도우 분석함수의 종류는 AVG, COUNT, MAX, MIN,STDDEV,SUM,VARIANCE,FIRST_VALUE,LAST_VALUE 등이 있다.
부분 집합을 결정하기 위한 범위는 CURRENTROW, UNBOUNDED PRECEDING, UNBOUNDED FOLLOWING 등을 지정할 수 있다.

【형식】
   (SUM | AVG | MAX | MIN | COUNT | STDDEV | VARIANCE | FIRST_VALUE | LAST_VALUE)
   ({ | * }) OVER
   ([PARTITION BY [,...]]
   ORDER BY  [collate clause]
   [ASC | DESC] [NULLS FIRST | NULLS LAST] [,...]
   ROWS | RANGE
   {{UNBOUNDED PRECEDING |  PRECEDING} | BETWEEN
   {UNBOUNDED PRECEDING |  PRECEDING}
   AND {CURRENT ROW |  FOLLOWING}}


OVER FROM, WHERE, GROUP BY, HAVING 절이 처리된 후에 적용되며, 함수를 적용하기 위한
행의 정렬 기준 또는 대상 행 집합에 대한 윈도우 정의
ROWS | RANGE 윈도우의 크기를 결정하기 위한 행 집합을 정의
• ROWS는 물리적인 단위에 의해 윈도우 크기 지정
• RANGE는 논리적인 상대 번지에 의해 윈도우 크기 지정
BETWEEN...AND 윈도우의 시작 위치와 마지막 위치 지정
UNBOUNDED PRECEDING 윈도우의 시작 위치는 각 분할의 첫 번째 행
UNBOUNDED FOLLOWING 윈도우의 마지막 위치는 각 분할의 마지막 행


PseudoColumn을 의미하는 것#


ROWID Each row in the database has an address
ROWNUM 테이블에서 select 되어진 행의 순서번호
LEVEL 테이블에서 행(row)의 계층관계를 가리키는 일련번호 순서


LPAD, RPAD : 문자열 채우기#

문법 :

lpad ('string', n [, 'string_pad')
rpad ('string', n [, 'string_pad')


예제 :

select lpad('*', 5, '%') lpad, rpad('%', 5, '*') rpad from dual


결과 :


LPAD RPAD
%%%%* %****


설명 :


VSIZE : 문자의 길이를 구한다.#

예제 :

select vsize('가나다'), '가나다' from dual


결과 :


VSIZE(가나다) 가나다
6 가나다


출처 : http://ebizdocs.springnote.com/pages/1250050?print=1


Posted by 1010
02.Oracle/DataBase2009. 8. 12. 14:39
반응형
select *
FROM BIZ_MASTER
where case when ceo_name < 'ㄱ' then substr(ceo_name, 1, 1)
            when ascii('ㄱ') <= ascii(ceo_name) and
                 ascii(ceo_name)<= ascii('ㅎ') then ceo_name
            when ceo_name < '나' then 'ㄱ'
            when ceo_name < '다' then 'ㄴ'
            when ceo_name < '라' then 'ㄷ'
            when ceo_name < '마' then 'ㄹ'
            when ceo_name < '바' then 'ㅁ'
            when ceo_name < '사' then 'ㅂ'
            when ceo_name < '아' then 'ㅅ'
            when ceo_name < '자' then 'ㅇ'
            when ceo_name < '차' then 'ㅈ'
            when ceo_name < '카' then 'ㅊ'
            when ceo_name < '타' then 'ㅋ'
            when ceo_name < '파' then 'ㅌ'
            when ceo_name < '하' then 'ㅍ'
            else                  'ㅎ'
       end = 'ㄱ';



출처 : http://blog.naver.com/pro20cm/150021994738



---------------------------------------------------------------------------------------


1.Sample Data 입력


create table t_first (col1 varchar2(100));


insert into t_first values('토플');
insert into t_first values('깡다구');
insert into t_first values('거울');
insert into t_first values('땅끝마을');
insert into t_first values('success');
insert into t_first values('듀오백');
insert into t_first values('사랑');
insert into t_first values('나오미');
insert into t_first values('미국');
insert into t_first values('naver');
insert into t_first values('뻥이야');
insert into t_first values('토마토');
insert into t_first values('새해');
insert into t_first values('premature');
insert into t_first values('찜질방');
insert into t_first values('사진');
insert into t_first values('fallen');
insert into t_first values('energy');
insert into t_first values('햄버거');
insert into t_first values('ㄱ');
insert into t_first values('ㄴ');
insert into t_first values('ㄷ');
insert into t_first values('가');
insert into t_first values('나');
insert into t_first values('다');


select * from t_first;


2.Data가 소량이라면 다음처럼 하면 됩니다.


select *
from t_first
where case when col1 < 'ㄱ' then substr(col1, 1, 1)
            when ascii('ㄱ') <= ascii(col1) and
                 ascii(col1)<= ascii('ㅎ') then col1
            when col1 < '나' then 'ㄱ'
            when col1 < '다' then 'ㄴ'
            when col1 < '라' then 'ㄷ'
            when col1 < '마' then 'ㄹ'
            when col1 < '바' then 'ㅁ'
            when col1 < '사' then 'ㅂ'
            when col1 < '아' then 'ㅅ'
            when col1 < '자' then 'ㅇ'
            when col1 < '차' then 'ㅈ'
            when col1 < '카' then 'ㅊ'
            when col1 < '타' then 'ㅋ'
            when col1 < '파' then 'ㅌ'
            when col1 < '하' then 'ㅍ'
            else                  'ㅎ'
       end = 'ㄱ';                    <== 이 부분을 바꿔가면서 테스트해 보면 됩니다.


select * from t_first
order by col1;


COL1
깡다구
거울


3.그러나 Data의 양이 많고 검색할 때 반드시 인덱스를 이용해야 한다면 다음처럼

  해야 합니다. 8i이후부터 가능한 FBI(function-based index)를 활용하는 예제입니다.

  이 예제는 dba 권한을  가진 유저로 테스트한 것입니다.


-- 함수 생성

create or replace function sf_ganada
  (p_name varchar2)
  return varchar2
  deterministic
is
  v_ret varchar2(10);
begin

  v_ret := case when p_name < 'ㄱ' then substr(p_name, 1, 1)
                when ascii('ㄱ') <= ascii(p_name) and
                     ascii(p_name)<= ascii('ㅎ') then p_name
                when p_name < '나' then 'ㄱ'
                when p_name < '다' then 'ㄴ'
                when p_name < '라' then 'ㄷ'
                when p_name < '마' then 'ㄹ'
                when p_name < '바' then 'ㅁ'
                when p_name < '사' then 'ㅂ'
                when p_name < '아' then 'ㅅ'
                when p_name < '자' then 'ㅇ'
                when p_name < '차' then 'ㅈ'
                when p_name < '카' then 'ㅊ'
                when p_name < '타' then 'ㅋ'
                when p_name < '파' then 'ㅌ'
                when p_name < '하' then 'ㅍ'
                else                  'ㅎ'
           end;

  return v_ret;
end sf_ganada;
/


-- 인덱스 생성
create index t_first_col1_fbi_idx
on t_first(sf_ganada(col1));


-- 통계 생성

analyze table t_first compute statistics
  for table
  for all indexed columns
  for all indexes;


-- 세션 환경 설정
alter session set QUERY_REWRITE_ENABLED=TRUE;
alter session set QUERY_REWRITE_INTEGRITY=TRUSTED;


-- 테스트 및 실행계획

select col1, sf_ganada(col1)
from t_first
where sf_ganada(col1) = 'ㄱ';


Execution Plan
----------------------------------------------------------
0   SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=4 Bytes=36)  
1 0     TABLE ACCESS (BY INDEX ROWID) OF 'T_FIRST' (Cost=2 Card=4 Bytes=36)  
2 1         INDEX (RANGE SCAN) OF 'T_FIRST_COL1_FBI_IDX' (NON-UNIQUE) (Cost=1 Card=4)

참고 1 : FBI(function-based index, 함수기반 인덱스)를 사용하려면...


# You must have the following initialization parameters defined

   to create a function-based index:

   -- QUERY_REWRITE_INTEGRITY set to TRUSTED
   -- QUERY_REWRITE_ENABLED set to TRUE
   -- COMPATIBLE set to 8.1.0.0.0 or a greater value


# The table must be analyzed after the index is created.


# The query must be guaranteed not to need any NULL values
   from the indexed expression, since NULL values are not stored in indexes.



참고 2 : 비슷한 문제 => http://blog.naver.com/orapybubu/40021815464

=================================================================================

자음까지는 잘 모르겠고...


select *

from table

where 한글 >= "가"

and     한글 < "나"


이렇게 하면 "가"부터 "깋" 까지는 가지고 옵니다.

   where decompose(mycolumn) like substr(decompose('가'),0,1)||'%'

================================================================

bulls1223 님 말 맞긴한대요 DECOMPOSE 는 유니코드 아니면 안됩니다.

한글로 테스트는 안해봐서 모르겠는대요... 그리고 9i 이상만 되는거 같내요

http://download-west.oracle.com/docs/cd/B10501_01/server.920/a96540/functions34a.htm#1000002


다른방법으론... 테이블 일일이 만들어서 검색하는방법이 있습니다.

 도서관리 프로그램 같은대서 주로 사용하는대요

도서관가면 ㄱ 210.0 ㄴ   이런거 있잔아요 이게 도서명 하고 저자명 각각 쓰는건대요

테이블보면

ㄱ  가 각 간 ~~~ 이런식으로  ㄱ 들어가는건 모두 들어있더군요.. 이걸가지고 검색하더군요... 받침은 안들어갑니다. ... 악 이런거...


다 만들어진건 찾기 힘들겁니다.  정해야된다면 직접만드시는게...

Posted by 1010
02.Oracle/DataBase2009. 8. 10. 18:08
반응형



오라클 clob 예제

by kkaok
2003-06-27


Lob type이란?

lob(Large Object) 타입은 대용량 데이터를 저장하기위한 데이터 타입으로 오라클 8버전부터 지원된다.


Lob 타입의 특징

이전에 대용량 처리는 long 타입으로 처리를 할 수 밖에 없었다. 그런데 이 칼럼은 한테이블에 하나만 사용할 수 있으며 최대 크기가 2GB였다. 더군다나 검색을 구현하기가 어려워 포기를 해야 했다. 그래서 이런 문제를 보안하기 위 나온 것이 Lob 타입이다. Lob 타입은 테이블에 여러개의 컬럼을 생성할 수 있으며 최대 크기가 4GB이다. 또한 long 타입보다 훨씬 쉬운 검색기능을 제공한다.


Lob type의 종류

이전에 대용량 처리는 long 타입으로 처리를 할 수 밖에 없었다. 그런데 이 칼럼은 한테이블에 하나만 사용할 수 있으며 최대 크기가 2GB였다. 더군다나 검색을 구현하기가 어려워 포기를 해야 했다. 그래서 이런 문제를 보안하기 위 나온 것이 Lob 타입이다. Lob 타입은 테이블에 여러개의 컬럼을 생성할 수 있으며 최대 크기가 4GB이다. 또한 long 타입보다 훨씬 쉬운 검색기능을 제공한다.

BLob (Binary Large Object), 이진 바이너리 데이터의 저장시 사용된다.
CLob (Character Large Object), 문서 데이터의 저장시 사용된다.
BFILE 외부 파일에 저장된 이진 데이터가 있는 경로의 저장시 사용된다.

Clob에 저장하기

  1: import java.sql.*;
  2: import java.io.*;
  3: import oracle.sql.*;
  4: import oracle.jdbc.driver.*;
  5: ...
  6: 
  7: public void insertQuery(UploadBoard up,int re_step,int re_level) 
         throws Exception  
  8: {
  9:   ResultSet rs   = null;
 10:   PreparedStatement pstmt = null;
 11:   Connection conn = null;
 12:   String query = "insert into "+up.getTableName()+" (seq,re_step,
           re_level,name,title,pwd,email,readnum,writeday,ip,relativeCnt,
               homepage,imgInfo,content,tag) 
                   values(?,?,?,?,?,?,?,0,sysdate,?,0,?,?,empty_clob(),?)";
오라클 명령어 empty_clob()을 이용해 공간을 확보한다.
13: try{ 14: conn = DBManager.getClobConnection(); 15: conn.setAutoCommit(false);
CLOB column을 업데이트 하는동안 다른 process의 접근을 막기위해
setAutoCommit(false)를 반드시 설정해야 한다. 이부분이 가장 중요하다.
16: pstmt = conn.prepareStatement(query); 17: pstmt.setInt(1,up.getSeq()); 18: pstmt.setInt(2,re_step); 19: pstmt.setInt(3,re_level); 20: pstmt.setString(4,up.getName()); 21: pstmt.setString(5,up.getTitle()); 22: pstmt.setString(6,up.getPwd()); 23: pstmt.setString(7,up.getEmail()); 24: pstmt.setString(8,up.getIp()); 25: pstmt.setString(9,up.getHomepage()); 26: pstmt.setString(10,up.getImgInfo()); 27: pstmt.setString(11,up.getTag()); 28: pstmt.executeUpdate(); 29: pstmt.close(); 30: String query2 = " select /*+ index_desc("+up.getTableName()+ " "+up.getTableName()+"_indx) */ content from "+ up.getTableName()+" where seq = ? for update ";
for update를 이용해 CLOB column을 lock한다.
31: pstmt = conn.prepareStatement(query2); 32: pstmt.setInt(1,up.getSeq()); 33: rs = pstmt.executeQuery(); 34: if(rs.next()) { 35: CLOB clob = ((OracleResultSet)rs).getCLOB(1); 36: Writer writer = clob.getCharacterOutputStream(); 37: Reader src = new CharArrayReader(up.getContent().toCharArray()); 38: char[] buffer = new char[1024]; 39: int read = 0; 40: while ( (read = src.read(buffer,0,1024)) != -1) { 41: writer.write(buffer, 0, read); // write clob. 42: } 43: src.close(); 44: writer.close(); 45: } 46: conn.commit(); 47: conn.setAutoCommit(true);
CLOB column에 데이터을 저장하였다면 commit()을 실행시키고
conn.setAutoCommit(true)로 다시 설정한다.
48: }finally{ 49: DBManager.close(rs,pstmt,conn); 50: } 51: }


Clob 불러오기

     ...
  1: public BoardTable getViewData(String tableName,int seq) throws Exception
  2: {
  3:   BoardTable bTable = new BoardTable();
  4:   String query = " select * from "+tableName+" where seq = ? ";
  5:   ResultSet rs = null;
  6:   PreparedStatement pstmt = null;
  7:   Connection conn = null;
  8:   try{
  9:     conn = DBManager.getConnection();
 10:     pstmt = conn.prepareStatement(query);
 11:     pstmt.setInt(1,seq);
 12:     rs = pstmt.executeQuery();
 13:     if (rs.next()) {
 14:       ...
 15:       ...      
 16:       StringBuffer output = new StringBuffer();
 17:       Reader input = rs.getCharacterStream("content");
 18:       char[] buffer = new char[1024];
 19:       int byteRead;
 20:       while((byteRead=input.read(buffer,0,1024))!=-1){
 21:         output.append(buffer,0,byteRead);
 22:       }
 23:       input.close();
 24:       bTable.setContent(output.toString()); 
CLOB 데이터를 불러오기 위해서는 위에서처럼
rs.getCharacterStream("content")로 불러서 StringBuffer에 담아야 한다.
25: ... 26: ... 27: } 28: } finally { 29: DBManager.close(rs,pstmt,conn); 30: } 31: return bTable; 32: }


================================================
    * Oracle Community OracleClub.com
    * http://www.oracleclub.com
    * http://www.oramaster.net
    * 운영자 : 김정식 (oramaster _at_ empal.com)
  ================================================
Posted by 1010
02.Oracle/DataBase2009. 7. 29. 16:30
반응형
OTN Logo


Oracle SQL Developer 1.5: Feature List

게시일: 2008년 4월

이 문서는 Oracle SQL Developer 1.5의 전체 기능 목록을 제공합니다. (별도의 Oracle SQL Developer 1.5 신기능) 문서도 있습니다)

목록

  1. 개요
  2. 아키텍처
  3. 데이터베이스 커넥션
  4. 커넥션 네비게이터
  5. SQL 워크시트
  6. SQL 및 PL/SQL 편집
  7. 내보내기 및 들여오기
  8. 보고
  9. SQL*Plus 지원
  10. 타사 데이터베이스 지원
  11. 마이그레이션 워크벤치
  12. Oracle Application Express 3.0.1
  13. Preferences
  14. 버전 통제

1.  개요

다운로드 사이트 OTN
비용 무료
오라클 지원 데이터베이스 지원 계약 고객을 위한 메타링크를 통해 지원 가능
릴리스

최초 릴리스: SQL Developer 1.0 (2006년 3월)

  Release SQL Developer 1.1 (2006년 12월)
  Release SQL Developer 1.2 (2007년 6월)
  Release SQL Developer 1.2.1 (2007년 8월)
  Release SQL Developer 1.5 (2008년 4월)

2.  아키텍처 및 일반 구조

아키텍처 Java IDE
  커넥션 네비게이터
  다중 접속
  DB 지원 (non-Oracle)
  Microsoft SQL Server, Microsoft Access, MySQL 및 Sybase를 위한 읽기 전용 지원
글로벌화 변환 UI (1.5.1에서 9개국 언어 번환 기능 지원 예정)
  아시아 / 멀티 바이트
  서유럽
GUI 현대식 IDE 인프라
  온라인 지원
  HTML
  단축 키
설치 (Release 1.5) 풋프린트 (38.4MB)
  Dependencies JRE (27MB)
  전체 다운로드 크기 (77 MB)
  Oracle Home 불필요
플랫폼 지원 Windows (with Windows Installer )
  Linux (with RPM install)
  Mac OS/X
데이터베이스객체 스키마 및 객체 유형 전반을 검색
  DB 객체 검색 및 확장 검색 다이얼로그. 파라미터, 선언 및 사용법 같은 코드의 객체 검색 가능.
고급 필터링 확장 필터링:
  - 다양한 필터 옵션 및 기준
  - AND or OR 필터링 구현 (All or Any 선택)
  - 기타 사용자 필터링은 가시적 객체를 갖고 있지 않는 사용자를 걸러 내기 위한 OBJECT_COUNT 포함
엔진 검색 Ask Tom
  Oracle doc
  Search Doc 10.2
  Search Doc 9.2
  Search Forums
  Search Google
  Search 메타링크
메뉴

외부 툴 지원

  DDL 및 데이터 내보내기
  데이터베이스 객체 검색
  쿼리 빌더
확장자

SQL Developer는 확장성 있는 IDE 기반으로 구현됨
  - Build 완전한 Java 확장자 구현
  - XML을 위한 확장 후크 사용

커넥션 네비게이터 데이터베이스 기록 관리 실행 (SYS 혹은 SYSTEM 등 모든 권한 접속에 대한 컨텍스트 메뉴를 마우스 오른쪽 클릭)
  데이터베이스 기록 관리 실행 (SYS로)하여 데이터베이스 종료 및 재시작
  스키마의 모든 객체를 위한 DB Doc 생성 (커넥션에 대한 컨텍스트 메뉴를 마우스 오른쪽 클릭). 브라우저에 생성된 index.html 파일을 열고 객체 점검.
스키마 복사

하나의 스키마 컨텐츠를 다른 스키마로 복사

  객체를 드롭, 절단 혹은 복사
  실행할 액션 보고 사전 점검
  결과 보고 로깅
Schema Diff

2 스키마 사이의 SQL Difference 구문을 비교, 생성

  객체 선택 후 비교
  비교 객체 보고
  차이 및 실행할 SQL 코드 목록화
  스크립트 아웃풋을 선택 커넥션에 실행할 SQL 워크시트에 실행

3.  데이터베이스 커넥션

커넥션 커넥션 생성, 저장, 업데이트 및 명칭 변경
  기본 Thin JDBC
  사용자 정의 JDBC URL
  TNS 커넥션
  Connection Manager를 통한 커넥션
  암호화된 비밀번호
  LDAP 커넥션
  외부 인증
  프록시 커넥션
  비밀번호 만료 시, 새로운 접속을 하도록 사용자 프롬프팅
타사 접근

읽기 전용 접속으로 객체 및 데이터 검색:
  - MySQL
  - SQL Server
  - MS Access
  - Sybase

TimesTen TimesTen 지원 통합

4.  커넥션 네비게이터

객체 검색 칼럼 헤딩을 통한 분류 허용
 

DDL 뷰

  종속성, 상세 정보, 통계 등 객체 정의 뷰
테이블

생성
  -표준 테이블
  -파티셔닝
  -인덱스 정렬
  -Global Temporary External
  -테이블 간편 생성
  -고급 생성
  -PK 트리거 및 시퀀스 생성
  -Lob 파라미터

 

수정
  -테이블 복사
  -칼럼 정상화
  -조건 생성, 활성화 및 활성 해제
  -관련 FK 조건 활성화 및 활성 해제

 

테이블 데이터
  -테이블 데이터 그리드 편집
  -열 복제
  -데이터 분류
  -SQL Where 절을 통한 필터링
  -단일 기록 뷰
  -열 카운트
  -내보내기
  -데이터 검색 (XMLType 칼럼)
  -CLOB 데이터 뷰

생성
  속성 뷰
  수정
  컴파일링 무효화
  업데이트 뷰의 데이터 업데이트
동의어

생성  
   - 객체 기반
   - 명칭 기반

  속성 뷰
  수정
시퀀스 생성
  속성 뷰
  수정
  컨텍스트 메뉴를 마우스 오른쪽 클릭해 시퀀스 변경
패키지, 절차, 기능 생성
  속성 뷰
  실행
  PL/SQL 아큐먼트 뷰
  컴파일 (개별 선택, All or Invalid)
  Debug로 컴파일
  "Create Body" 사양으로부터 디폴트 골조 실행
  파일 기반 PL/SQL 지원
  - pl/sql 파일 열기, 편집 및 저장
  - 데이터베이스 업데이트 위해 스키마에 pl/sql 파일 컴파일링
유형 생성
  속성 뷰
  실행
트리거 생성
  트리거 소스 편집
  수정
  마스터/디테일 포맷 트리거 탭. 디테일로 트리거 코드 표시
데이터베이스링크 생성
  속성 뷰
  수정
  테스트
인덱스

생성
  -Non-unique
  -Unique
  -텍스트 인덱스
  -비트맵

  속성 뷰
도메인 인덱스 모든 접근 가능 스키마의 기존 인덱스 유형에 인덱스 생성
메시지 오류 디스플레이 업데이트로 오라클 오류에 대한 자세한 정보 표시
  컴파일링 관련, 상태 바에 성공 메시지 표시
디렉토리 속성 뷰
종합 뷰 생성
  속성 뷰
  실행
  고급 체크박스
  - 객체 등의 선택 항목을 선택하여 Select 구문을 선언적으로 정의
  - 인덱스 추가
  - 파티션 추가
  "New Index"를 사용하여 종합 뷰에 인덱스 추가
종합 뷰 로그 종합 뷰 로그 생성 및 편집을 위한 새로운 인터페이스
큐 및 큐 테이블 검색 및 뷰
Java 검색
  로딩
기타 사용자스키마 검색  
휴지통 비우기
  객체 드롭 취소
XML 스키마 생성
  속성 뷰
객체 네비게이터 통제 필터/찾기
  새로 표시
  그리드 데이터를 파일로 다운로드
사용자 승인 및 역할 등으로 사용자 생성
  사용자 역할, 승인 및 권한 편집
Schema Diff 소스 스키마 및 객체를 데스티네이션 스키마와 비교해 DDL 생성
  SQL을 SQL 워크시트로 전송
DBA 유틸리티 데이터 관리
 

데이터베이스 사용자 관리
  -사용자 생성
  -사용자 변경
  -사용자 드롭

 

DDL 생성
  -객체 기준 DDL
  -스키마 기준 DDL

Application Express 3.0.1 데이터베이스 스키마와 관련된 모든 Oracle APEX 애플리케이션에 접속 및 검색 (애플리케이션 및 페이지 레벨)
  컨텍스트 메뉴를 사용하여 Oracle APEX 애플리케이션 내보내기 및 들여오기

5.  SQL 워크시트

데이터 그리드 기록 버튼 복제
  한 번에 하나의 기록을 보기 위한 단일 기록 "피봇"
  SQL 워크시트에 칼럼 기록 및 이전 순서 취소 허용
  테이블 데이터 편집기의 날짜 필드용 캘린더 프롬프트
  그리드에 대한 컨텍스트 메뉴
  필터로 열 카운트
  데이터 그리드 검색
  칼럼 크기 자동 조정 (데이터 그리드 및 칼럼 헤더 컨텍스트 메뉴에서)
  그리드 이외 모든 곳에서 모든 선택 사항 복사 및 붙여 넣기
  선택 사항을 복사 Excel에 붙여 넣기
  Excel에서 선택 사항 복사해 데이터 그리드로 붙여 넣기
쿼리 빌더 기본 쿼리 생성
  쿼리 실행하여 데이터 테스트
  SQL을 SQL 워크시트로 전송
스닙펫 스닙펫을 SQL 워크시트로 드래그 앤 드롭
  스닙펫 관리
  - 새로운 캐터고리 생성
  - 새로운 스닙펫 생성
SQL 워크시트 구문 실행
  스크립트 실행
  워크시트 커넥션 변경
 

파일 지원
  - 검색
  - 커넥션 변경
  - 실행
  - 편집
  - 저장

  SQL 구문 포맷
  괄호 매칭
  ref 커저 출력 표시 지원
  BLOB, CLOB, xml, 커저 지원
  Code insight on
  - 테이블 별칭
  - 스키마
  - 부분 테이블 + ctrl +[space] (예정)
  - ctrl +[space] (예정)
  테이블 설명 (F4)
  탭 명 개선: 워크시트 명을 'MyTab Name' 으로 설정
  SQL*Plus 지원 (아래 목록 참조)
  장기 실행 스크립트 일시 정지
  일시 정지 스크립트 재개
  rownum을 선택해 전체 열 선택
  SQL 워크시트의 X쿼리
  SQL 이력
  DBMS 아웃풋
  OWA 아웃풋
  변수 결합
  옵션 실행
  모드를 preference로 자동 실행 (디폴트로는 활성화 안됨)
  코드 포맷
  파일로 내보내기
  쿼리 취소
  Code Insight 개선. 다양한 객체 유형을 위한 코드 완성 기능 사용 가능
  SQL Formatting 대체. 여백, 탭, 코마 적용, 활자 케이스, 신규 라인 등을 통제하는 SQL Formatter preferences 참조.
  자주 사용하는 코드를 위한 코드 템플릿. Preferences에서 이들을 생성한 후, 키 조작을 통해, 코드 편집기 및 SQL 워크시트에서 코드 템플릿 들여오기. ctrl+shift+T)
  코드 템플릿 공유 가능: /Application Data/Sql Developer/CodeTemplate.xml
  플래시백. 10g 및 11g에서, 데이터 플래시백 가능. 테이블 플래시백 참조.
  활자 케이스 변화를 위한 키 조작. (컨텍스트 메뉴에서도 가능.) 조작 키는 ctrl-quote
  Refactor 코드, SQL 워크시트 혹은 코드 편집기의 컨텍스트 메뉴 참조
  장기 실행 쿼리 커넥션을 위한 별도의 공유 워크시트. 조작 키는 ctrl+shift+N. 이는 별도의 공유 워크시트를 생성. 공유 워크시트는 다음과 같이 표시: HR_ _1
  SQL History는 스크립트 실행 혹은 구문 실행을 위한 F5 및 F9 키 조작으로 커맨드 저장. @filename을 실행하면, 파일의 모든 커맨드가 아니라, 이것이 History에 저장됨. ctrl-up 및 ctrl-down 키는 SQL 워크시트에서 이전에 실행된 커맨드를 추가하고 스크롤링.
  구문 삽입, 수정, 삭제, 병합 및 선택을 위해 네비게이터에서 워크시트로 드래그 앤 드롭. Preference 설정.
 

테이블의 데이터 그리드가 Sort 보존.

  데이터 그리드 필터가 이전 필터 옵션의 드롭 목록을 보존
튜닝 Autotrace 지원
  Explain plan 지원
  *.trc 파일을 SQL Developer에서 열어 포맷된 추적 파일 생성

6. SQL 및 PL/SQL 편집

편집 OS 파일 북마크
  PL/SQL DB 객체 북마크
  코드 폴딩
  코드 포맷
  Code Insight (코드 완성)
  코드 스닙펫 뷰어
  편집기로 객체 드래깅
  파일 운영 (저장, 열기)
  인라인 컴파일링 오류
  표준 편집기 운영
  Leading Remarks로 파일 열기 지원
  구문 하이라이팅
PL/SQL 디버거 열 형식 검사
  구분점 설정
튜닝 계층적 프로파일러(Oracle 11g R1 이상의 커넥션용)

7. 내보내기 및 들여오기

데이터 들여오기 SQL Developer를 사용하여 스프레드시트 (XLS 포맷) 데이터를  테이블로 들여오기
  xls 스프레드시트의 테이블 들여오기 생성
  CSV로부터 들여오기
데이터 내보내기 한 번에 한 개 이상의 테이블 내보내기 (with or without DDL)
  다음으로 내보내기  
  -CSV
  - XML
  - Text
  - HTML
  - XLS
  - SQL 삽입 구문
  - SQL*Loader Syntax
DDL 내보내기 Export DDL 내보내기는 드롭 객체 포함을 허용
  다중 테이블을 위한 데이터 구문 삽입
  스키마 명칭 공표 금지 옵션
  한 번 클릭으로 전체 스키마 내보내기
  컨텍스트 메뉴에서 파일, 워크시트 혹은 클립보드로 내보내기

8.  리포팅

리포팅 제공 마스터/상세 보고를 통한 데이터베이스 세션 검색
  전체 보고서 내보내기
  모든 보고서 들여오기
  마우스 오른쪽 클릭 기능 강화
  세션 종료
  SQL 리포팅
  추적 세션
  보고서 결과를 텍스트, CSV, XLS, XML, HTML, INSERT, Loader로 내보내기
  ASH 및 AWR 보고서 (Oracle 11g R1 이상의 커넥션 및  Oracle Diagnostic pack 라이센스 사용자용)
사용자 정의 보고 차트화 (테이블에서 그룹, 시리즈, 데이터 선택)
  선적 보고서 복사해 사용자 정의 보고로 붙여 넣기
  차트 보고서 생성 및 실행
  마스터 상세 보고 생성 및 실행
  스크립트 사용한 보고서 생성
  Create a report with plsql-dbms_output
예를 들면,  begin dbms_output.put_line('<h1>hello</h1>'); end;로 보고서 생성
  포맷 코드 (예를 들면, select text from user_source where rownum < 100)으로 보고서 생성
  게이지로 보고서 생성
  보고서 Id를 사용해 사용자 정의 보고서를 클릭
  변수 결합을 위한 프롬프트 정의
  드릴다운 링크
  사용자 정의 보고서 생성, SQL 입력 위한 파일 검색 및 제출 허용
  사용자 정의 보고서 들여보기 및 내보내기
  사용자 정의 보고서 공유
  1.0에 생성된 사용자 정의 보고서 열기
Oracle Application Express Report 워크스페이스, 애플리케이션, 페이지 및 스키마 검색 지원
기타 보고서 메인 툴 메뉴의 세션 모니터링 보고서
  네비게이터의 커넥션 컨텍스트 메뉴의 데이터베이스 관리 보고서
마이그레이션 보고서 타사 데이터베이스 마이그레이션 지원을 위한 일련의 보고서

9. SQL*Plus 지원

모든 SQL 및 PL/SQL 커맨드는 SQL 워크시트에서 직접 Oracle Database로 넘겨져 지원됩니다. SQL Developer에서 사용되는 SQL*Plus 커맨드는 데이터베이스로 넘겨지기 전에 SQL 워크시트에 의해 해석되어야 됩니다.

SQL 워크시트는 현재 수 많은 SQL*Plus 커맨드를 지원합니다. SQL 워크시트에 의해 지원되지 않는 커맨드는 무시되어 Oracle Database로 넘겨지지 않습니다. Oracle SQL Developer SQL 워크시트에 의해 지원되는 SQL*Plus 커맨드는 아래 목록과 같습니다.

커맨드

참고

@


@@


acc[ept]


autotrace  
clear screen  

conn[ect]

스크립트 실행 컨텍스트에서만 유효. CONNECT 뒤의 스크립트로 되어 있는 커맨드는 대체 스키마에서 운영되지만 스크립트 완성 후에는 , SQL 워크시트가 선택된 커넥션의 컨텍스트 내부에 남게 됩니다.

def[ine]


desc[ribe]


doc[ument]


echo  
errors  
esc[ape]  

exec[ute]


exit

실행 중단 및 콤보 상자의 커넥션 원상 회복

feed[back]  
ho[st]  
pau[se]  

pro[mpt]


print  

quit

실행 중단 및 콤보 상자의 커넥션 원상 회복

rem[ark]


sta[rt]


term[out]  
timi[ng]  

undef[ine]


user  
var[iable]  
ver[ify]  

whenever


xquery  

10.  타사 데이터베이스 지원

타사 검색 Microsoft Access
  Microsoft SQL Server
  MySQL Database
  Sybase Adaptive Server
마이그레이션 서비스 Microsoft SQL Server에서 Oracle로
  Microsoft Access에서 Oracle로
  MySQL에서 Oracle로
  T-SQL을 PL/SQL로 변환
  Access를 PL/SQL로 변환
  Sybase Adaptive Server to Oracle

11. 마이그레이션 워크벤치

타사 데이터베이스 지원 Microsoft Access
  Microsoft SQL Server
  MySQL Database
  Sybase Adaptive Server
커넥션 타사 데이터베이스 검색
마이그레이션 옵션 Quick Migration Wizard는 최소 권한 마이그레이션 지원으로 DBA 권한 불필요
  단계적 마이그레이션으로 마이그레이션 프로세스의 모든 단계 통제.
  정밀 마이그레이션 지원으로 마이그레이션을 위한 특정 객체 선택 가능.
  복잡한 객체 마이그레이션은 저장된 절차, 트리거 및 뷰 지원.
변환 변환 스크래치 편집기는 단일 구문 마이그레이션 지원
  Translation Difference Viewer는 구문 및 블록 매칭을 통해 일대일 비교 제공.

12.  Oracle Application Express (APEX) 지원

커넥션 네비게이터 데이터베이스 커넥션 Oracle APEX 데이터베이스 스키마 생성
  애플리케이션 및 페이지 레벨에서 데이터베이스 스키마와 관련된 모든 Oracle APEX 애플리케이션 검색
  컨텍스트 메뉴를 사용하여 Oracle APEX 애플리케이션 내보내기 및 들여오기
리포팅 워크스페이스
  애플리케이션
  페이지
  스키마

13.  Preferences

데이터베이스 Autotrace
  NLS
  타사 JDBC Driver
환경 워크시트
  Object Viewer
  연결된 SQL 워크시트 열기
  Auto-freeze/pin 탭
  5000 이상의 Fetch 사이즈 허용
  SQL Array Fetch 사이즈
코드 편집기 북마크
  Insight
  라인 거터
  디스플레이 설정
PL/SQL 디버거 PL/SQL 디버깅을 위해 프로브 디버거 사용
  구분점 속성
  Watches
  Inspector
사용자 정의 확장 사용자 정의 보고서 공유
  새로운 컨텍스트 메뉴 추가
  새로운 탭 생성

14.  버전 통제

버전 통제 CVS 및 서브버전과로 통합
 

버저닝 네비게이터

  서브버전 레포지터리 생성
  파일 검사 및 실행
  브랜치/태그
  비교 및 병합
  충돌 해결
파일

파일 시스템 파일 검색을 위한 파일 네비게이터

  파일 이력 뷰
Posted by 1010
02.Oracle/DataBase2009. 7. 29. 13:53
반응형

oracle 공백 제거

홍 길 동  -> 홍길동

홍   길동 -> 홍길동

SELECT RTRIM(REPLACE(필드명' ','')) FROM 테이블명;

Posted by 1010
02.Oracle/DataBase2009. 7. 14. 10:22
반응형
출처: http://www.devpia.com/DevStudy/Lecture/OffLineDetail.aspx?nSemiID=1431&lectype=evt

데브피아에 DB 튜닝관련 컬럼 연재가 2회차가 올라왔습니다. ^^

 지난회에는 인덱스를 생성했으나 컬럼의 가공, 내부적 변형, null과의 비교, 부정형 조건등으로 인하여 인덱스를 사용하지 못하는 경우를 보았다.
그럼 과연 인덱스를 타기만 하면 무조건 빠를까?
불행하게도 그렇지 않다. 대부분의 경우는 빠르겠지만 경우에 따라서는 인덱스를 타기 때문에 느려지는 경우가 많이 발생한다.

EMPLOYEE에 성별 컬럼을 추가하고 절반정도 되게 남성과 여성을아래와 같은 분포도로 넣었다.

SELECT GENDER , COUNT(*) CNT, ROUND(COUNT(*) / 15132,3)*100 RATIO FROM EMPLOYEES
GROUP BY GENDER;

G
----
F
M
CNT
--------
7590
7542
RATIO
---------
50.2
49.8
 
그리고 아래와 같은 INDEX를 생성하였다.
CREATE INDEX IDX_GENDER ON EMPLOYEES(GENDER);
그러면 이제 2개의 SQL의 수행 결과를 보자.
첫번째 경우는 INDEX를 탄경우다.
아래와 같이 HINT를 주어서 OPTIMIZER의 PLAN을 고정하였다.
/*+ INDEX(E IDX_GENDER) */ 는 E라는 별명의 테이블에 IDX_GENDER이라는 INDEX를 이용하여 테이블에 데이터를 가져오라는 뜻이다.
SELECT /*+ INDEX( E IDX_GENDER) */ GENDER, COUNT(*), AVG(SALARY)
FROM EMPLOYEES E
WHERE GENDER = 'M'
GROUP BY GENDER

Call
----------
Parse
Execute
Fetch
----------
Total

Count
----------
1
1
2
----------
4
CPU Time
----------
0.000
0.000
0.030
----------
0.030
Elapsed Time
-------------
0.000
0.000
0.026
-------------
0.026
Disk
----------
0
0
0
----------
0
Query
----------
0
0
127
----------
127
Current
----------
0
0
0
----------
0
Rows
----------
0
0
1
----------
1
Misses in library cache during parse: 0
Optimizer goal: RULE
Parsing user: SCOTT (ID=54)

Rows
----------
0
1
7542
7542
Row Source Operation
---------------------------------------------------
STATEMENT
SORT GROUP BY NOSORT (cr=127 pr=0 pw=0 time=25567 us)
TABLE ACCESS BY INDEX ROWID EMPLOYEES (cr=127 pr=0 pw=0 time=15176 us)
INDEX RANGE SCAN IDX_GENDER (cr=16 pr=0 pw=0 time=61 us)OF IDX_GENDER (NONUNIQUE)
두번째 경우는 INDEX를 타지 않은 경우다.
아래와 같이 HINT를 주어서 OPTIMIZER의 PLAN을 고정하였다.
/*+ FULL(E) */ 는 E라는 별명의 테이블을 할 때 테이블 전체를 다 읽어서 처리(FULL TABLE SCAN)하라는 뜻이다.
SELECT /*+ FULL(E) */ GENDER, COUNT(*), AVG(SALARY)
FROM EMPLOYEES E
WHERE GENDER = 'M'
GROUP BY GENDER

Call
----------
Parse
Execute
Fetch
----------
Total

Count
----------
1
1
2
----------
4
CPU Time
----------
0.000
0.000
0.010
----------
0.010
Elapsed Time
-------------
0.000
0.000
0.014
-------------
0.015
Disk
----------
0
0
0
----------
0
Query
----------
0
0
115
----------
115
Current
----------
0
0
0
----------
0
Rows
----------
0
0
1
----------
1
Misses in library cache during parse: 0
Optimizer goal: RULE
Parsing user: SCOTT (ID=54)

Rows
----------
0
1
7542
Row Source Operation
---------------------------------------------------
STATEMENT
SORT GROUP BY NOSORT (cr=115 pr=0 pw=0 time=14410 us)
TABLE ACCESS FULL EMPLOYEES (cr=115 pr=0 pw=0 time=181 us)
인덱스를 탄 경우는 0.03초가 걸렸고 인덱스를 타지 않은경우는 0.01초가 걸렸다.
인덱스를 타서 3배나 더 느려졌다!. 이것이 가능한가? 그러면 왜 인덱스를 탔는데도 시간이 더 걸리는 것인가?
이유는 Disk io에 있다. 일반적으로 Full table scan을 할때는 한번에 1개의 block씩 i/o를 하지 않고 muti block를 한번에 요구한다. 그 이유는 읽을 양이 많다고 미리 가정하기 때문이다. 따라서 Oracle의 경우 db_file_multiblock_read_count라는 파라미터가 있고 일반적으로 8또는 16을 설정한다. 만약 16이라면 한번 I/O에 16개의 BLOCK을 읽어오게 되는것이다.
따라서 EMPLOYEE 115BLOCK을 한번에 16개씩 읽으면 약 8번의 IO 요청으로 완료가 된다.
그러나 Index를 사용할 경우 index를 사용하면 기본적으로 대량의 io가 발생할 것이라고 가정하지 않기 때문에 1개의 block씩 i/o를 하게 된다.
따라서 16개의 index block과 115개의 block의 물리적 i/o가 발생한다 16+115를 하면 총 131번의 물리적 io가 발생하게 되는것이다. 논리적으로는 인덱스 1개보고 테이블 1개 블락을 읽고를 7542번+1번을 하게되는 것이다. 마지막 1번은 다음에 더 이상 ‘M’이 없는지 확인하기위해서 1번 더 읽는다. 어째든 인덱스를 사용되는 것이 더욱 느리다는 것이다. 현지 EMPLOYEES 테이블은 15132건이다. 만약 이 데이터가 많아진다면 차이는 점점 더 많이 날것이다.

그러면 어느정도은 INDEX를 타고 어느 정도는 Full Table Scan이 오히려 더 좋은가?
시스템의 성능또는 데이터의 양에 따라 차이가 조금씩있으나 일반적인 기준은 있다.
아래 TYPE이라는 컬럼에 A-F까지 값을 가지고 있으며 가각 49.8%부터 0.9%까지의 분포를 가지는 값들을 가지고 있다.
SELECT TYPE , COUNT(*) CNT, ROUND(COUNT(*) / 15132,3)*100 RATIO FROM EMPLOYEES
GROUP BY TYPE;

T
--------
A
B
C
D
E
F
CNT
--------
7542
4533
1515
799
603
140
RATIO
---------
49.8
30
10
5.3
4
0.9
아래는 예제로 사용되었던 SQL과 그에 따른 응답시간을 비교한 표이다.

FTS(Full Table Scan) SQL
SELECT /*+ FULL(E) */ GENDER, COUNT(*), AVG(SALARY)
FROM EMPLOYEES E
WHERE TYPE = 'F'
GROUP BY GENDER;

Rows
--------
0
1
140
Row Source Operation
---------------------------------------------------
STATEMENT
1 HASH GROUP BY (cr=115 pr=0 pw=0 time=6925 us)
140 TABLE ACCESS FULL EMPLOYEES (cr=115 pr=0 pw=0 time=10323 us)
INDEX(Index Scan) SQL
SELECT /*+ INDEX(E IDX_TYPE) */ GENDER, COUNT(*), AVG(SALARY)
FROM EMPLOYEES E
WHERE TYPE = 'F'
GROUP BY GENDER;

Rows
--------
0
1
140
140
Row Source Operation
---------------------------------------------------
STATEMENT
HASH GROUP BY (cr=87 pr=0 pw=0 time=3227 us) 140
TABLE ACCESS BY INDEX ROWID EMPLOYEES (cr=87 pr=0 pw=0 time=2956 us)
INDEX RANGE SCAN IDX_TYPE (cr=2 pr=0 pw=0 time=539 us)OF IDX_TYPE (NONUNIQUE)
 
결과를 보자 약 15132건의 테이블을 ACCESS하는데 10%이상이 되는 경우는 FTS이 더빠르고 10%이하인 경우는 INDEX를 타는 경우가 더 빠르다.
10% 미만일때는 INDEX를 타고 10%가 넘으면 인덱스를 안타게 할수 있는가?
결론적으로 가능하다.
아래 SQL을 보자 2개의 SQL을 UNION ALL로 결합하고 비교조건을(굵은색)을 줌으로서 논리적 비교를 통해서 실제로 FTS의 조건은 타지 않고 INDEX쪽만 수행하도록 하였다.
아래 수행결과를 보면 INDEX를 타는 곳에서만 ROWS가 나온 것을 알수있다.
SELECT /*+ FULL(E) */ GENDER, COUNT(*), AVG(SALARY)
FROM EMPLOYEES E
WHERE TYPE = 'F'
   AND TYPE IN ( 'A','B','C')
GROUP BY GENDER
UNION ALL
SELECT /*+ INDEX(E IDX_TYPE) */ GENDER, COUNT(*), AVG(SALARY)
FROM EMPLOYEES E
WHERE TYPE = 'F'
   AND TYPE IN ( 'D','E','F')
GROUP BY GENDER;

Rows
--------
0
1
0
0
0
1
140
140
Row Source Operation
---------------------------------------------------
STATEMENT
UNION-ALL (cr=87 pr=0 pw=0 time=2743 us)
HASH GROUP BY (cr=0 pr=0 pw=0 time=235 us)
FILTER (cr=0 pr=0 pw=0 time=8 us)
TABLE ACCESS FULL EMPLOYEES (cr=0 pr=0 pw=0 time=0 us)
HASH GROUP BY (cr=87 pr=0 pw=0 time=2477 us)
TABLE ACCESS BY INDEX ROWID EMPLOYEES (cr=87 pr=0 pw=0 time=2328 us)
INDEX RANGE SCAN IDX_TYPE (cr=2 pr=0 pw=0 time=205 us)OF IDX_TYPE (NONUNIQUE)
그렇나 이렇게 프로그램을 한다면 프로그램이 힘들어 질것이다. 따라서 현재 Optimizer들은 실제 값에 따라서 FTS이 유리한지 아니면 INDEX SCAN이 유지한지 값을 보고 PLAN이 바뀌도록 되어있다. 물론 이를 위해서는 컬럼에 대한 분포도 정보를 DB가 가지고 있어야 한다. 이는 ANALYZER를 통해서 DB가 취득하게 된다.

그럼 이제 간단하다 10%이상에 데이터를 INDEX를 타면 속도가 오히려 느려지므로 10%이하의 데이터를 찾고자 할 때만 INDEX를 생성하면 간단하게 해결될것이다!
그러나 과연 그럴까?
INDEX를 생성하면 일반적으로 SELECT의 속도는 향상을 보지만 반대로 INSERT,UPDATE,DELETE는 저하되게 된다.
위에 도표를 보면 INDEX의 숫자가 증가함에 따라서 속도가 느려지는 것을 알수 있다. 즉, 인덱스의 생성으로 SELECT는 빨라질수도 있고 느려질수도 있다. 그러나 DML(INSERT,UPDATE,DELETE)는 항상 느려진다. 따라서 INDEX를 무작정 다는 것은 DML 성능을 느리게 한다.
그럼 어떤 기준으로 인덱스를 생성할지 말지를 결정할 것인가?
아래 2가지 시간을 고령하자.
이익시간 = INDEX생성으로 빨라진시간 * 수행 QUERY수
비용시간 = INDEX생성으로 느려진 INSERT시간 * INSERT수행횟수
                + INDEX생성으로 느려진 UPDATE시간 * UPDATE수행횟수
                + INDEX생성으로 느려진 DELETE시간 * DELETE수행횟수

이익시간이 비용시간 보다 크다면 인덱스를 생성하는 것이 좋을 것이다. 반대로 이익시간 < 비용시간 보다 작다면 인덱스를 만드는 것이 손해보는 경우다.
이런 경우라면 인덱스를 만들면 안되는 것이 유리하다 할수 있다. 그러나 반드시 그런 것은 아니다. 그것은 수행 시간을 고려해야한다. 낮에일반적으로 QUERY가 빠르게 수행되고 주로 밤에 BATCH에서 DML이 수행되고 있다고 가정할 때 DML이 더 느려지는 것이 그렇게 문제가 되지 않는다면 INDEX를 생성할 수도 있는것이다. 어디까지나 Application 사용의 관점에서 효율적인 것을 찾는 것이 중요하다.
인덱스를 사용하여 손해보는 경우는 아래와 같다.

  • 같은 값이 많은 컬럼
    • INDEX를 타면 10%이상 선택하는 경우
    • 예) 남녀성별등..
  • 조회보다 DML의 부담이 큰 경우
    • 이익시간 < 비용시간 경우
    • 그러나 이때도 사용환경을 고려하여 인덱스를 생성할 수 있다.
  • 데이터가 적은 테이블
    • 일반적으로 db_file_multiblock_read_count보다 적은 수의 BLOCK을 가진테이블은 INDEX를 타지 않는 것이 빠르다.
    • 그러나 integrity를 위해서 PK와 FK는 달아야 한다.

이번 회에는 INDEX를 타서 오히려 손해를 보는 경우와 그를 방지하는 방법을 보았다.
인덱스를 생성한다고 인덱스를 반드시 타는 것도 아니며 또한 인덱스를 탄다고 반드시 빠른 것도 아니다. 따라서 INDEX의 생성과사용 전략은 그렇게 쉬운 문제가 아니다. 빠른 시스템을 위해서는 고려할 점이 많다는 것이다. 물론 필자가 다룬 것은 테이블중에 일반테이블과 일반 INDEX에 대해서만 다루었기때문에 PARTITION이나 BITMAP같은 다른 구조의 인덱스에서는 다른 특성을 가진다. 그러나 이러한 것은 대용량이나 DW의 특수한 용도에 사용되므로 대부분의 경우에는 고려하지 않아도 크게 문제되지 않을 것이다.

못조록 필자의 글이 독자들에게 도움이되는 길이기를 바라면서 이글을 마무리하고자 한다.
마지막으로 당부 드리고 싶은 말은 SQL을 작성하시고 항상 PLAN을 확인하시기 바랍니다.
PLAN에 익숙해지고 OPTIMIZER를 이해할 때 비로소 OPTIMIZER가 여러분의 심부름꾼이 될수 있기때문이다.


Posted by 1010