728x90

오라클의 adump, bdump, udump, 리스너 로그, 아카이브 로그 등을 백업할 수 있으면 백업하는 것을 권장한다. 하지만 대부분의 경우 백업의 필요성이 절실하지 않기 때문에 삭제한다.

 

각종 로그의 자동관리를 위하여 첨부한 파일과 같이 CRONTAB에 등록하여 관리하면 편리하다.
각각의 로그관리에 대한 정책이 필요하다.

정책 예시)
1. alert 로그       : 월별로 로그를 관리. 영구 보관하는 것이 좋다.
                      compress 명령으로 압축하여 보관.
2. adump audit 파일 : 180일 정도 유지, 매일 180일이 지난 trc파일을 삭제
3. bdump trace 파일 : 90일 정도 유지, 매일 90일이 지난 trc파일을 삭제
4. udump trace 파일 : 90일 정도 유지, 매일 90일이 지난 trc파일을 삭제
5. 리스너 로그      : 리스너를 로깅하도록 설정했을 경우 월별로 로그를 관리.

                      180일이 지난 파일은 삭제.
                      compress 명령으로 압축하여 보관.
6. 아카이브로그 파일 : 기본적으로 1주일에 1번 이상 FULL BACKUP을 받을 경우
   백업 툴에서 아카이브로그를 관리해 주지 않을 경우 등록하여 사용
   7일전 아카이브로그 파일 삭제.

쉘 예시) 쉘 스크립트 작성 시 오타에 주의할 것
#######################################################
#### alert.log                                     ####
#######################################################
nDate=`date +%Y%m%d`
cp $ORACLE_BASE/admin/TESTDB/bdump/alert_TESTDB.log $ORACLE_BASE/TESTDB/bdump/alert_TESTDB.log.$nDate
cat /dev/null > $ORACLE_BASE/admin/TESTDB/bdump/alert_TESTDB.log
compress -vf $ORACLE_BASE/TESTDB/bdump/alert_TESTDB.log.$nDate

 

#######################################################
#### listener.log                                  ####
#######################################################
nDate=`date +%Y%m%d`
cp $ORACLE_HOME/network/admin/listener.log $ORACLE_HOME/network/admin/listener.log.$nDate
cat /dev/null > $ORACLE_HOME/network/admin/listener.log
compress -vf $ORACLE_HOME/network/admin/listener.log.$nDate

 

#######################################################
#### audit                                         ####

#######################################################
# 1주일이 지난 *.aud를 찾아 삭제
find $ORACLE_BASE/admin/TESTDB/adump \( -ctime +7 -name '*.aud' \) -exec rm -f {} \;

 

#######################################################
#### .trc                                          ####
# 30일이 지난 *.trc를 찾아 삭제                    ####
#######################################################
find $ORACLE_BASE/admin/TESTDB/bdump \( -ctime +30 -name '*.trc' \) -exec rm -f {} \;
find $ORACLE_BASE/admin/TESTDB/udump \( -ctime +30 -name '*.trc' \) -exec rm -f {} \;

 

#######################################################
#### archive log                                   ####
#######################################################
# 3일이 지난 *.arc를 찾아 삭제
find /archive_log \( -ctime +3 -name '*.arc' \) -exec rm -f {} \;

 

#########################################################
# 특정 디렉토리가 70%이상이면 3일지난 *.arc를 찾아 삭제 #
#########################################################
#!/usr/bin/ksh
A=`df -k /archive_log | grep -v "용량" | awk '{print $5}' | sed 's/%//'`
if [ $A > 70 ] ;
then
    find /archive_log \( -ctime +3 -name '*.arc' \) -exec rm -f {} \;
fi

728x90
728x90

1. 클라이언트 NLS_LANG

   많은 오라클 엔지니어들이 아직도 이경우 제대로 정리되지 않은 부분입니다.

   결론부터 말하면 DB의 CHAR SET이  UTF8이라고 하더라도

   클라이언트 LOCALE은 KSC5601 혹은 WIN949이어야 합니다.

   문서도 있는데 링크는 기억나지 않고^^;

   UTF8이 서버 로케일일 경우이건 뭐건, 클라이언트 로케일은 해당 국가 로케일이 되어야 합니다.

   간략한 테스트는

   LENGTHB와 CONVERT 함수를 이용해서 테스트를 해보면 됩니다.

   DB가 UTF8일 경우

   클라이언트 LOCALE이 UTF8로 올릴 경우 한글이 2바이트로 됩니다.

   CONVERT로 바꿀 때 SOURCE를 KOC5601로 처리해야 됩니다. (하지만 DUMP를 떠보면 다르게 나옵니다)

   DB가 UTF8이라고 클라이언트 로케일을 UTF8로 바꿀 경우 치러야 할 대가가 만만치 않습니다.

   특히 EXPORT,IMPORT할 때 NLS_LANG을 잘못한 경우...--;

 

2. CHAR TYPE 문제

   하나의 칼럼이 CHAR TYPE인데 이를 UTF8로 바꾼다면?

   해당 데이터가 오로지 영숫자만 있다면 상관없겠으나

   한글도 들어간 칼럼이라면?

   DATA TYPE 변경 없이 일괄적으로 칼럼의 LENGTH를 늘리면

   스페이스가 들어가는 경우가 발생합니다.

   즉, CONVERSION이 잘못된 경우이죠.

   이때는 먼저 SOURCE에서 CHAR -> VARCHAR2로 변경한 뒤에 작업하셔야 합니다.

   일반적으로 특수한 경우(좀있다 얘기하겠습니다)를 제외하고 이렇게 변경한 뒤에

   어플리케이션 영향도는 없다고 보셔도 됩니다.

   그리고 변경하는데 생기는 부하는 거의 없습니다. 단, 피크시간대는 절대 피하셔야죠

   LIBRARY CACHE 쪽에서 해당 테이블을 참조하는 오브젝트가 모두 재컴파일 됩니다.

 

3. VARCHAR2(4000)칼럼의 문제

   LOB나 LONG을 사용하지 않고 VARCHAR2로 칼럼을 정의하고 게시판 본문이나

   각종 텍스트를 처리하는 테이블이 있습니다.

   이 경우 UTF8로 넘어갈 때 BYTE가 늘어나 해당 레코드를 처리할 때 에러가 납니다.

   EXP를 사용할 경우 그냥 에러로그에 남으니까 그나마 낳습니다.

   DB LINK로 땡길 경우 전체 트랜잭션이 에러나면 많이 힘들게 되죠.

   그리고 실질적으로 VARCHAR2(4000)을 넘기 때문에 데이터가 잘리는 문제가 생깁니다.

   이를 해결하려면 LOB로 바꿔야 하는데 이경우 어플리케이션 테스트를 제대로 못하면 문제가 커집니다.

   JAVA같은 경우 TYPE문제가 걸리죠

   이경우 최선의 방법은 없습니다.

   저같은 경우 어플리케이션 담당자를 설득해서 해당 칼럼 데이터의 나머지를 버렸습니다.

   물론 당근으로는... LOB로 바꿀 경우 어플리케이션을 바꿔야 한다는 것. 하지만 일부 데이터의 OVER LENGTH부분을

   버리면 아무것도 손댈 필요가 없다는 것...

   아무튼, 이부분은 DBA가 단독으로 결정하면 안됩니다.

 

4. UTL_FILE을 이용한 FILE CONTROL 문제

   이건 상당히 골치 아픈 문제입니다.

   대상 DB와 어플리케이션이 UTL_FILE을 사용해서 데이터를 읽거나 쓰지 않는다면  여러분은 일단 복받으신 겁니다.

   일반적으로 소켓으로 주고받는 데이터(뭐 금융권 전문이나 애니링크같은)는 구분자가 아니라 자리수로 구분합니다.

   FILE에서는 한글2바이트,영문1바이트이기 때문에 그걸로 미리 자리수가 정해져 있죠.

   이를 UTL_FILE이나 LOADER로 올려서 SUBSTRB로 잘라서 쓰는 경우가 있습니다.

   그런데 디비에서 처리하면 한글3바이트,영문1바이트입니다. 즉, 정해진 자리수로 자를 수 없습니다.

   당연히 배치에서 데이터가 잘못 처리됩니다.

   이럴 때 첫번째로 생각하는 방법은 CONVERT로 KSC5601로 바꿔서 기존 데이터 처리 방식으로 처리하면 됩니다.

   하지만 이런 경우에도 글자는 깨집니다. 왜냐하면 SUBSTRB(SUBSTR 포함)는 해당 로케일을 따라가기 때문에

   CONVERT로 바꾼다고 해도 보장을 못합니다.

   이를 해결할려면 UTL_RAW 팩키지를 사용해야 합니다.

   특히, 잘라서 올리는 것만이 아니라 자리수에 맞춰서 UTL_FILE로 WRITE 할 경우 CONVERT를 제대로 안하면

   전문처리 등에서 대형사고를 일으킵니다.

 

5. PARTIAL MULTI BYTE 에러

   이는 KSC5601 -> UTF8로 DB LINK로 처리할 때 많이 생깁니다.

   원인은 KSC5601 자체 있습니다.

   UTF 코드는 자신이 파싱 못하는 문자는 받아들이지 않으나 KSC5601은 다 받아들입니다.

   즉, 파싱되지 않는 쓰레기 데이터도 해당 칼럼에 들어갑니다.(예를 들어 ¿ 같은 문자)

   그나마 눈에 보이는 문자면 다행이죠... 아예 조회시 누락되는 바이트도 있습니다.

   물론 TO_SINGLE_BYTE FUNCTION으로 대부분 해결됩니다. 그래서 가능한 이방식을 먼저 적용합니다.

   하지만 그렇게 되지 않는 경우도 발생합니다.

   이런 경우는 일일이 찾아서 해당 데이터를 고쳐야 합니다.

   제일 편한 방법은 EXPORT/IMPORT로 넣어서 ERROR LOG를 보면 됩니다.

   그런데 해당 사이트에 여러개의 DB가 있고 해당 데이터가 원천데이터가 아닌 경우는 끝까지 추적해서 그걸 잡아내지 않으면

   마이그레이션 이후에도 계속 에러납니다.

   예를 들어 UTF로 바꾼 DB는 정보계이고 계정계는 아직 KSC5601이라면 마감배치 돌릴 때마다 에러나겠죠?

 

6. COLUMN LENGTH의 문제

   한글은 2->3바이트, 영숫자는 1->1 바이트이므로 계산상 해당 칼럼을 1.5배로 늘려주면 아무 이상이 없어야 하는데요...

   안타깝게도 안그렇습니다. 위의 PARTITAL MULTI BYTE에러와 연관되는 문제인데... 1바이트로 처리되어야하는 문자가

   3바이트로 처리되는 경우가 발생합니다. 이것을 피하고 싶으면  TO_SINGLE_BYTE로 처리해야 합니다.

   그러나... 이경우 문제가 있습니다. 일단 처리시간이 오래걸립니다.(마이그레이션은 제한된 시간에 해야 합니다)

   그렇다고 기존 SOURCE를 전부 UPDATE처리하자니 뒷감당이 안됩니다.( 문제가 발생하는 레코드의 칼럼만

    변경하면 됩니다만 이것을 추적해서 찾을 시간이 없습니다. 물론 시간이 있다면 하시는게 베스트죠. 그러나 그럴 시간을

    확보할 수 있을까요?)

    결국 나중에는 2배로 늘리고, 다시 2.5~3배로 늘렸습니다. 시간이 부족하기 때문에 벌어진 일이죠.

    이렇게 해도 큰 문제가 없는 이유는 대부분 이런 문제를 일으키는 데이터는 조회조건에 걸리는 칼럼이 아니라

    조회결과로 걸리는 칼럼이기 때문입니다.(비즈니스 어플리케이션을 이해하신다면 수긍하실겁니다)

    이것은 편법입니다. 원칙적으로는 이런 데이터 클린징작업을 먼저 수행해야 합니다.

728x90
728x90

SQL*LOADER 사용시에 여러가지 적절한 옵션 사용과 테이블에 대한 설정값들을 변경시켜줌으로써 
많은 성능 향상을 가져올수 있다.

다음은 그 권장되는 설정법들을 설명한 것이다.

1. DIRECT PATH LOAD를 사용한다. Direct path load는 load되는 테이블이나 파티션에 exclusive access를 요구한다. 
추가적으로 트리거는 자동으로 disable되고 제약조건은 로드가 완료될때까지 defer(연기) 된다.
 

2. direct path load로 데이타를 로드시에 모든 CHECK 와 REFERENCE 무결성 제약조건은 자동으로 DISABLE된다. 
그러나 그밖의 다른 타입의 제약조건 NOT NULL, UNIQUE, PRIMARY KEY 조건들은 반드시 DISABLE 시켜준다. 
작업 완료후에 수동으로 enable시켜준다. 
 

3. 정렬된 순서로 데이타를 load한다. 미리 sorting 된 데이타는 정렬에 필요한 공간temporary 영역 사용을 최소화한다. 
SQL*LOADER 옵션에서 SORTED INDEXES 를 CONTROL파일에 기술한다.
 

4. 인덱스 MAINTANCE 를 연기(DEFERRING)하라. 인덱스는 데이타가 insert하거나 delete 또는 key 컬럼이 업데이트 
될때마다 자동으로 maintance 를 실시한다.따라서 많은 양의 데이타를 load할때 작업이 종료된 후에 maintance를 한다면 
좀더 빠를 것이다. SKIP_INDEX_MAINTENANCE = TRUE  를 설정하면 인덱스 세그먼트의 상태가 “ INDEX UNUSABLE”상태가 
되어있더라도 LOADER시작시에 인덱스 MAINTANCE를 SKIP한다. 
 

5. UNRECOVERABLE 을 사용해서 REDO 생성을 DISABLE시킨다. 모든 recover 시에는 redo log파일이 필요하다. 
그러나 redo log 생성은 부하가 많기 때문에 disable시키면 그만큼 속도는 빠르게 된다. 
그러나 LOADER 작업 중간에 FAILURE 가 발생한다면 처음부터 load작업을 다시 해야한다. 
따라서 리두로그를 생성하지 않기때문에 loader 작업 후에는 반드시 백업하도록 한다.
 

6. 단일 파티션에 loading 하도록 한다. 파티션 테이블에 데이타 load시 기타 사용자는 다른 파티션 에 접근 할 수 있다. 
APRIL 파티션을 로드시에 jan 에서 april 까지 쿼리를 실행하는 유저를 차단하지 못한다. 따라서 부하가 증가한다. 
 

7. Parallel 로 로드를 한다. 파티션으로 구성되어 있다면 parallel 로 다중 파티션을 로드할 수 있다. 
 

8. STREAMSIZE 파라미터는 SQL*LOADER client 에서 oracle server로 direct path stream buffer 의 크기(bytes)를 
지정한다. 기본값은 256000 bytes 이다.  
또한 columnarrayrows 또한 direct path column array 에 전송하는 row의 갯수를 지정한다.기본값은 5000이다.


9. 만일 load되는 데이타가 중복되는 날자값을 많이 가지고 있다면 DATE_CACHE 파라미터를 설정해서 DIRECT PATH LOAD
시에 더 나은 성능을 보장할 수 있다. CACHE에 CONVERION 되는 DATE 의 사이즈(엔트리)를 지정한다. (기본값은 1000) 

728x90
728x90

LMT(Locally Managed Tablespace)사용하기



작성일: 2002-11-11
작성자: 강명규(kang@dbakorea.pe.kr)
OS: Linux 2.4.19
Oralce: Oracle EE 8.1.7

미리 말하자면, 당신의 오라클서버가 이 기능을 지원한다면 무조건 이 기능을 사용하라.

오라클은 tablespace, extent, data block 이라는 관점에서 공간할당(Space Allocation)을 관리한다.
간단히 data block < extent < tablespace 라고 생각하면 되겠다.
data block은 보통 몇개의 OS블럭으로 구성되는 DB의 기본 I/O단위가 된다.
extent는 또 몇개의 오라클 data block으로 구성된다.
보통 테이블등의 오브젝트는 이 extent단위로 할당을 받아 segment를 이루게 된다.
tablespace는 이 모든 것들을 포함하는 컨테이너로서의 역활을 수행한다.


Dictionary managed tablespaces
별다른 조치를 하지 않았다면 테이블스페이스의 공간할당에 대한 관리는
다른 오브젝트와 동일하게 Data Dictionary가 한다.
오라클 8.0.x이전 버전의 경우, 이것만이 가용한 방식이다.


Locally Managed Tablespaces (LMT)
하지만 8.1.x이후부터는 '테이블스페이스에 의한 extent관리'라고 불리는 공간할당관리옵션을 사용할 수 있다.
테이블스페이스에 대한 extent allocation 관리를 해당 테이블스페이스 자신이 스스로 할 수 있다는 것이다.
즉, 성능병목현상을 유발할 수 있는 Data Dictionary에 의한 관리로부터 벗어날 수 있다는 것이다.
이러한 테이블스페이스는 자신이 소유한 각 데이터파일에 대한 블럭의 사용유무를 추적하기 위해 '비트맵'을 유지한다.
비트맵내의 각 비트(bit)는 블럭 혹은 블럭들의 그룹에 해당한다.


LMT의 장점
1. temporary tablespace에 적합하게 사용될 수 있다.
2. 주기적인 tablespace의 coalesce가 불필요하다.
   (tablespace의 coalesce를 모른다면 자신이 DBA인가 의심하십시오)
3. 모든 extent는 균등한 크기를 갖게 하며, 테이블스페이스레벨에서 이를 강제하여
   사용자의 잘못된 extent크기지정의 위험을 피할 수 있다.

주의점
1. temporary tablespace에는 UNIFORM extent allocation만 가능
2. NEXT, PCTINCREASE, MINEXTENTS, MAXEXTENTS, and DEFAULT STORAGE 저장옵션은 유효하지 않다.


EXTENT할당 방식
오라클이 새로운 extent를 할당할 수 있는 자유공간을 찾는 방식은 다음과 같다.
해당 테이블스페이스가 소유한 데이터파일들중 한 놈을 선택, 그 데이터파일의 '비트맵'을 검색하여
요구되는 개수의 인접 자유블럭(adjacent free block)을 가진 놈을 찾는다.
만일, 데이터파일이 충분한 인접자유공간을 가지고 있지 못한다면, 또다른 놈을 검색할 것이다.
extent가 할당해제될때, 오라클은 해당 데이터파일의 비트맵을 수정한다.




EXTENT할당(Extent Allocation)방식에는 2가지가 있다.

Automatic Extent Allocation
사용자는 초기 extent크기만을 결정하고, 이후의 추가적인 extent는 오라클이 결정한다.
(이때, extent크기는 64KB, 1MB, 8MB, 64MB 순으로 사용될 것이다. )

SQL> create tablespace ts_dbakorea_lmt_auto
  2  datafile '/u01/app/oracle/oradata/db/ts_dbakorea_lmt_auto01.dbf' size 10m
  3  extent management local autoallocate;  

Tablespace created.

SQL>

Uniform Extent Allocation
생성될 extent크기를 사용자가 정할 수 있다.(default: 1MB)
이후, 생성되는 모든 extent는 초기에 정한 이 extent의 크기를 가지게 된다.
따라서, 이 테이블스페이스내에서 생성되는 테이블, 인덱스등은 모두 같은(균등한) extent크기를 가지게 될 것이다.
당연히 tablespace의 fragmetation은 발생하지 않으므로, coalesce과정이 필요없다.

SQL> create tablespace ts_dbakorea_lmt_uni
  2  datafile '/u01/app/oracle/oradata/db/ts_dbakorea_lmt_uni01.dbf' size 10m
  3  extent management local uniform size 1m;

Tablespace created.

SQL>


자, 그럼 dba_tablespaces에 질의하여 tablespace의 정보를 확인해 보자.
당연히, TS_DBAKOREA_LMT_UNI, TS_DBAKOREA_LMT_AUTO는 extent_management가 local로 되어 있다.
allocation_type은 uniform의 경우 UNIFORM으로, AUTOALLOCATE의 경우 SYSTEM으로 되어 있음을 알수 있다.
특의하게 TS_DBAKOREA_LMT_AUTO의 경우 NEXT_EXTENT가 정해져 있지 않음을 유의하자.

SQL> select tablespace_name, initial_extent, next_extent, min_extents, max_extents,
  2  pct_increase, extent_management, allocation_type
  3  from dba_tablespaces;

TABLESPACE_NAME      INITIAL_EXTENT NEXT_EXTENT MIN_EXTENTS MAX_EXTENTS PCT_INCREASE EXTENT_MAN ALLOCATIO
-------------------- -------------- ----------- ----------- ----------- ------------ ---------- ---------
SYSTEM                        65536       65536           1  2147483645           50 DICTIONARY USER
RBS                          524288      524288           8        4096           50 DICTIONARY USER
TOOLS                         32768       32768           1        4096            0 DICTIONARY USER
TEMP                          65536       65536           1                        0 DICTIONARY USER
USERS                        131072      131072           1        4096            0 DICTIONARY USER
INDX                         131072      131072           1        4096            0 DICTIONARY USER
TS_DBAKOREA_LMT_UNI         1048576     1048576           1  2147483645            0 LOCAL      UNIFORM
TS_TEST                       20480       20480           1         249           50 DICTIONARY USER
TS_CORRUPT_TEST               20480       20480           1         249           50 DICTIONARY USER
TS_TEMP                       20480       20480           1         249           50 DICTIONARY USER
TS_DBAKOREA_LMT_AUTO          65536                       1  2147483645              LOCAL      SYSTEM

11 rows selected.

SQL>

AUTOALLOCATE의 경우, 처음 테이블의 크기(처음 EXTENT의 크기)는 64KB부터 시작한다.
테이블의 크기가 1MB가 될때까지 EXTENT는 64KB단위로 증가하고, 1MB가 된 이후부터는
EXTENT의 크기가 1MB단위로 증가하게 된다. 이후부터는 약간 다른데 64MB가 되었을때 8MB,
1GB가 되었을때 64MB단위로 EXTENT가 증가하게 된다. 따라서 위의 질의에서 NEXT_EXTENT가
명확히 보이지 않는 것이다.

LMT의 경우에서, EXTENT의 크기는 테이블스페이스 레벨에서만 관리되어 진다.
즉, LMT내의 테이블등의 오브젝트는 모두 테이블스페이스의 저장옵션을 따라 정해진다.





temporary tablespace를 locally managed로 변환하기

SQL> drop tablespace temp;

Tablespace dropped.

SQL> create temporary tablespace temp
  2  tempfile '/u01/app/oracle/oradata/db/ts_temp_lmt_uni01.dbf' size 10m
  3  extent management local uniform size 2m;

Tablespace created.

SQL> select tablespace_name, initial_extent, next_extent, min_extents, max_extents,
  2  pct_increase, extent_management, allocation_type
  3  from dba_tablespaces;

TABLESPACE_NAME                INITIAL_EXTENT NEXT_EXTENT MIN_EXTENTS MAX_EXTENTS PCT_INCREASE EXTENT_MAN ALLOCATIO
------------------------------ -------------- ----------- ----------- ----------- ------------ ---------- ---------
SYSTEM                                  65536       65536           1  2147483645           50 DICTIONARY USER
RBS                                    524288      524288           8        4096           50 DICTIONARY USER
TOOLS                                   32768       32768           1        4096            0 DICTIONARY USER
TEMP                                  2097152     2097152           1                        0 LOCAL      UNIFORM
USERS                                  131072      131072           1        4096            0 DICTIONARY USER
INDX                                   131072      131072           1        4096            0 DICTIONARY USER
TS_DBAKOREA_LMT_UNI                   1048576     1048576           1  2147483645            0 LOCAL      UNIFORM
TS_TEST                                 20480       20480           1         249           50 DICTIONARY USER
TS_CORRUPT_TEST                         20480       20480           1         249           50 DICTIONARY USER
TS_DBAKOREA_LMT_AUTO                    65536                       1  2147483645              LOCAL      SYSTEM

10 rows selected.

이렇게 생성된 temporary tablespace는 v$datafile이 아닌 v$tempfile에서만 보여진다.

SQL> select name from v$datafile;

NAME
----------------------------------------------------------------------------------------------------------------------------------
/u01/app/oracle/oradata/db/system01.dbf
/u01/app/oracle/oradata/db/rbs01.dbf
/u01/app/oracle/oradata/db/tools01.dbf
/u01/app/oracle/oradata/db/users01.dbf
/u01/app/oracle/oradata/db/indx01.dbf
/u01/app/oracle/oradata/db/ts_corrupt_test01.dbf
/u01/app/oracle/oradata/db/ts_test01.dbf
/u01/app/oracle/oradata/db/ts_dbakorea_lmt_uni01.dbf
/u01/app/oracle/oradata/db/ts_dbakorea_lmt_auto01.dbf

9 rows selected.

SQL> select name from v$tempfile;

NAME
----------------------------------------------------------------------------------------------------------------------------------
/u01/app/oracle/oradata/db/ts_temp_lmt_uni01.dbf

SQL>


더 많은 내용을 원한다면 dba_free_space, dba_extents뷰도 확인해보면 좋을 것이다.

이제 dictionary managed tablespace를 locally managed tablespace로 변경해 보겠다.
상호간의 변경은 8.1.6이상에서만 가능하므로 주의하기 바란다. 현재 필자는 8.1.7에서 테스트했다.
8.1.5는 locally managed tablespace -> dictionary managed tablespace 로의 변환만이 가능하다고 한다.

locally managed tablespace -> dictionary managed tablespace : DBMS_SPACE_ADMIN.TABLESPACE_MIGRATE_FROM_LOCAL
dictionary managed tablespace -> locally managed tablespace : DBMS_SPACE_ADMIN.TABLESPACE_MIGRATE_TO_LOCAL

temporary와 system tablespace는 locally managed 에서 dictionary-managed로 변환이 불가능하다.
SYSTEM의 경우, 새로 DATABASE를 생성할때 할 수 밖에.. 다른 방법이 있으려나?
오라클사는 locally managed tablespace를 사용하기를 권장하고 있므로 지금부터 바꿔보는 것은 어떨까?


SQL> select tablespace_name, extent_management, allocation_type
  2  from dba_tablespaces;

TABLESPACE_NAME                EXTENT_MAN ALLOCATIO
------------------------------ ---------- ---------
SYSTEM                         DICTIONARY USER
RBS                            DICTIONARY USER
TOOLS                          DICTIONARY USER
TEMP                           LOCAL      UNIFORM
USERS                          DICTIONARY USER
INDX                           DICTIONARY USER
TS_DBAKOREA_LMT_UNI            LOCAL      UNIFORM
TS_TEST                        DICTIONARY USER
TS_CORRUPT_TEST                DICTIONARY USER
TS_DBAKOREA_LMT_AUTO           LOCAL      SYSTEM

10 rows selected.

SQL> exec dbms_space_admin.tablespace_migrate_to_local('TOOLS');

PL/SQL procedure successfully completed.

SQL> exec dbms_space_admin.tablespace_migrate_to_local('RBS');

PL/SQL procedure successfully completed.

SQL> exec dbms_space_admin.tablespace_migrate_to_local('USERS');

PL/SQL procedure successfully completed.

SQL> exec dbms_space_admin.tablespace_migrate_to_local('INDX');

PL/SQL procedure successfully completed.

SQL> exec dbms_space_admin.tablespace_migrate_to_local('TS_TEST');

PL/SQL procedure successfully completed.

SQL> exec dbms_space_admin.tablespace_migrate_to_local('TS_CORRUPT_TEST');

PL/SQL procedure successfully completed.

SQL> select tablespace_name, extent_management, allocation_type
  2  from dba_tablespaces;

TABLESPACE_NAME                EXTENT_MAN ALLOCATIO
------------------------------ ---------- ---------
SYSTEM                         DICTIONARY USER
RBS                            LOCAL      USER
TOOLS                          LOCAL      USER
TEMP                           LOCAL      UNIFORM
USERS                          LOCAL      USER
INDX                           LOCAL      USER
TS_DBAKOREA_LMT_UNI            LOCAL      UNIFORM
TS_TEST                        LOCAL      USER
TS_CORRUPT_TEST                LOCAL      USER
TS_DBAKOREA_LMT_AUTO           LOCAL      SYSTEM

10 rows selected.

SQL> select tablespace_name, initial_extent, next_extent, min_extents, max_extents,
  2  pct_increase, extent_management, allocation_type
  3  from dba_tablespaces;

TABLESPACE_NAME                INITIAL_EXTENT NEXT_EXTENT MIN_EXTENTS MAX_EXTENTS PCT_INCREASE EXTENT_MAN ALLOCATIO
------------------------------ -------------- ----------- ----------- ----------- ------------ ---------- ---------
SYSTEM                                  65536       65536           1  2147483645           50 DICTIONARY USER
RBS                                    524288      524288           8        4096           50 LOCAL      USER
TOOLS                                   32768       32768           1        4096            0 LOCAL      USER
TEMP                                  2097152     2097152           1                        0 LOCAL      UNIFORM
USERS                                  131072      131072           1        4096            0 LOCAL      USER
INDX                                   131072      131072           1        4096            0 LOCAL      USER
TS_DBAKOREA_LMT_UNI                   1048576     1048576           1  2147483645            0 LOCAL      UNIFORM
TS_TEST                                 20480       20480           1         249           50 LOCAL      USER
TS_CORRUPT_TEST                         20480       20480           1         249           50 LOCAL      USER
TS_DBAKOREA_LMT_AUTO                    65536                       1  2147483645              LOCAL      SYSTEM

10 rows selected.

SQL>

728x90
728x90

Parallel DML은 기본적으로 session에 "enable" 되어 있지 않습니다. PDML과 serial DML의 locking, transaction, disk space requirement 등의 차이에 의해 PDML mode의 "enable"이 요구됩니다.

ALTER SESSION ENABLE PARALLEL DML;

따라서 Parallel DML이 "disable"되있을 경우 parallel hint나 table/index에 degree가 설정되어 있어도 이는 무시되게 됩니다. 물론 PDML mode가 "enable"되어 있어도 parallel hint나 table/index에 대한 degree가 설정되어 있어야 PDML로 수행 가능하다.


한 Transaction은 서로 다른 table에 대해 여러 PDML이 수행될 수 있습니다. 그러나 PDML로 변경된 table에 대해 해당 transaction 내에서 serial/parallel 명령(DML or Query)으로 access를 할 수 없습니다. 즉 commit/rollback 등으로 transaction을 완료 후에야 동일 table에 대한 operation이 가능합니다.
(참조 Note 201978.1 PDML Restrictions on Parallel DML)

Oracle 9i 이후에 intra-partition parallelism 개념이 소개되었습니다.
이 개념은 partition당 한개씩만 수행되는 parallel execution server의 제한을 완화(?) 시키는 개념입니다.
(참고 Note 241376.1 What is Intra-partition parallelism )

특정 세션의 PDML의 "enable" 여부는 v$session의 PDML_STATUS, PDDL_STATUS, PQ_STATUS column으로 확인 할 수 있습니다.

SQL> SELECT SID,PDML_STATUS, PDDL_STATUS, PQ_STATUS FROM V$SESSION;

SID PDML_STATUS PDDL_STATUS PQ_STATUS
---------- ------------ ------------ ------------
141 DISABLED DISABLED DISABLED
143 DISABLED ENABLED ENABLED
145 DISABLED ENABLED ENABLED
148 DISABLED ENABLED ENABLED
150 DISABLED DISABLED DISABLED

728x90
728x90

아직도 수많은 기업에서 성능 최적화를 수행하면 서도 주어진 SQL만을 그대로 최적화하려고 하는 경우가 많다. 물론 주어진 SQL의 튜닝을 통해 성능을 최적화할 수 있는 것은 분명하다. 하지만, 우리가 생각을 전환하여 기존이 방식과 다른 방식으로 수행하여 엄청난 성능 향상을 기대할 수 있는 경우도 많다. 대용량 데이터베이스로 변하고 있는 시점에서 성능 최적화를 위해 사용자 생각의 전환은 반드시 필요한 요소다.
 
권순용 | kwontra@hanmail.net
 
 
우리 주위에는 프로젝트의 성능을 향상시키기 위해 SQL 최적화에 전념하는 사이트들이 많이 있을 것이다. SQL 최적화를 통해 크게 성능 향상을 기대할 수 있는 것은 사실이다. 예전에는 성능 저하가 발생하는 경우 SQL 튜닝 보다도 해당 시스템의 CPU 또는 디스크 등의 자원을 증설하는 부분에 초점을 맞추었었다. 이와 달리 SQL을 튜닝하여 성능을 최적화하고자 하는 것은 매우 고무적인 현상임에는 틀림 없다.
 
그 만큼 관리자들의 생각이 IT 선진화로 가는 것은 아닐까? 하지만 아직도 SQL 튜닝을 고정 관념에 맞춰 그리고 그 자체로 튜닝하고자 하는 경우가 많은 것 같다. 우리가 조금만 다르게 생각한다면 SQL 튜닝의 효과를 배가 시킬 수 있다는 것을 아는가? 주어진 SQL을 그대로 보지않고 다르게 보는 순간 우리에게는 새로운 세상이 펼쳐질 것이다.
 
데이터 삭제를 DELETE로 수행하지 않고 데이터의 갱신을 UPDATE로 수행하지 않는다면 우리에게는 새로운 세상이 펼쳐질 것이다. 이제부터 이와 같은 현상에 대해 하나하나 자세히 확인해 보자.
 
 
DML은 왜 성능을 저하시키는가?
 
 
우리가 데이터를 저장하기 위해서는 INSERT를 수행하게 되고 데이터를 제거하기 위해서는 DELETE를 수행하게 된다. 또한, 기존의 데이터를 변경하기 위해서는 UPDATE를 수행하게 된다. 이와 같은 사실은 개발을 한번이라도 한 사람이라면 아니 SQL에 관련된 책을 한번이라도 본 사람이라면 누구나 알 수 있을 것이다.
 
DML 작업을 수행한다면 그리고 DML 작업을 수행해야 하는 데이터가 매우 많다면 많은 시간이 소요될 거라고 누구나 생각할 것이다. 그렇다면 이와 같이 대용량의 데이터에 대해 DML 작업을 수행하는 경우 어떤 이유에서 많은 시간이 소요되는 것일까? 이에 대해서는 많은 사람들이 정확한 개념을 갖고 있지 못하는 것 같다. ‘나를 알고 적을 안다면 100전 100승이 되듯이’ DML 작업의 성능을 최적화하기 위해서는 DML 작업이 왜 성능을 저하시키는지를 알아야 할 것이다. DML 작업이 왜 성능을 저하시키는지 정확히 이해하지 못한다면 우리는 어떤 방법을 사용해도 성능을 향상시킬 수 없을 것이다.
 
그럼 첫 번째로 INSERT의 성능 저하를 확인해 보자. INSERT는 데이터를 저장하는 SQL 중 하나로 아래와 같은 이유에서 많은 데이터의 저장 시 성능을 저하시키게 된다.
 
·로그 기록
·HWM BUMP UP
·인덱스의 개수
·롤백을 위한 로그 기록
·디스크 I/O
 
INSERT 작업은 위와 같이 4가지 현상에 의해 성능이 저하된다. 이는 어떤 데이터베이스를 이용해도 동일하게 발생하는 현상이다. 데이터베이스는 작업의 수행도 중요하지만 작업이 실패하거나 또는 다른 장애에 의해 시스템이 재기동 되는 등의 데이터베이스 장애에 대해 데이터를 보호해야 하는 중요한 책임을 가지고 있다.
 
이와 같은 이유에서 실제 데이터베이스에서 INSERT 작업을 수행하기 전에 어떤 작업을 수행하는지에 대한 로그를 기록해야 한다. 이와 같은 기법을 선 로그(LOG AHEAD) 기법이라고 한다. 실제 INSERT를 수행하기 전에 로그를 기록하기 때문에 우리는 언제든지 INSERT 작업 중 데이터베이스에 문제가 발생해도 복구가 가능하게 되는 것이다. 실제 INSERT 작업과 관계없는 로그를 기록해야 하기 때문에 INSERT의 성능은 저하된다.
 
그렇다면 HWM BUMP UP에 의한 성능 저하는 무엇을 의미하는 것인가? HWM BUMP UP은 오라클 데이터베이스의 내부적인 요소이다. 실제 INSERT를 수행하게 되면 해당 테이블에 할당되어 있는 공간에 데이터를 저장하게 되며 해당 공간을 익스텐트라고 부르게 된다. 익스텐트에는 HWM가 설정되어 있어 데이터는 HWM 앞의 블록에만 저장된다. 이 뜻은 무엇을 의미하는 것인가?
 
HWM 앞까지 데이터를 저장한 후에는 HWM가 뒤로 후진해야만 데이터를 INSERT할 수 있다는 의미가 된다. 이를 HWM BUMP UP이라 하며 많은 데이터를 INSERT하게 되면 HWM BUMP UP은 많은 횟수가 발생하게 될 것이다. 하지만 HWM BUMP UP은 고비용의 내부적인 작업이다. 따라서 대용량의 데이터를 저장한다면 HWM BUMP UP의 횟수 증가로 INSERT의 성능은 저하된다.
 
INSERT의 속도와 인덱스의 개수는 INSERT의 성능 향상을 위해 매우 중요한 요소이다. 데이터를 테이블에 저장하는 것은 여유 공간을 가지고 있는 데이터 블록에 해당 데이터를 저장하면 된다. 하지만 인덱스에는 정해진 위치가 존재하게 되므로 정해진 위치를 찾는 프로세스가 수행된다. 따라서 해당 테이블에 인덱스가 10개라면 이와 같이 저장되는 데이터에 대해 인덱스에서의 위치를 찾기 위해 정해진 위치를 찾는 프로세스가 10번 수행되어야 할 것이다. 이와 같기 때문에 인덱스의 개수가 많다면 INSERT의 성능이 저하되는 것은 당연한 사실일 것이다.
 
어떤 사이트에서 어떤 테이블에 10개의 인덱스가 존재했으며 이를 최적화하여 5개의 인덱스로 변경한 적이 있다. 단지 10개의 인덱스를 5개로 감소시키는 순간 SQL의 변경 없이 INSERT 작업은 4배정도의 성능이 향상되었다. 이는 4배의 성능 향상이 중요한 것이 아니라 인덱스가 INSERT 작업에 많은 부하를 발생시킨다는 중요한 사실을 우리에게 전해주는 것일 것이다.
 
롤백을 위한 로그 기록은 해당 작업을 수행한 후 작업을 취소하는 경우 이전 데이터로 복구하기 위해 이전 데이터의 값을 저장하는 것을 의미한다. 이와 같은 작업 또한 실제 데이터를 저장하는 작업과는 별개로 수행되므로 INSERT의 성능 저하를 발생시키게 된다.
 
HWM BUMP UP을 제외한 로그 기록, 인덱스 및 롤백을 위한 로그 기록은 모두 디스크 I/O를 발생시킨다. 또한, 실제 데이터를 저장하는 작업에서도 디스크 I/O가 발생하게 된다. 이와 같이 모든 단계에서 디스크 I/O가 발생하기 때문에 INSERT의 성능은 저하될 것이다.
 
두 번째로 UPDATE의 성능 저하를 확인해 보자. UPDATE는 이미 저장되어 있는 데이터에 대해 변경 작업을 수행하는 것이다. 이와 같은 UPDATE는 아래와 같은 요소에 의해 성능 저하가 발생하게 된다.
 
·로그 기록
·UPDATE 컬럼이 사용된 인덱스의 개수
·롤백을 위한 로그 기록
·디스크 I/O
 
UPDATE의 경우에는 HWM BUMP UP은 발생하지 않게 된다. 또한, 인덱스의 개수도 해당 테이블에 존재하는 모든 인덱스는 아니며 UPDATE가 수행되는 컬럼이 사용된 인덱스의 개수를 의미하게 된다. UPDATE가 수행되면 해당 컬럼을 인덱스의 컬럼으로 구성하고 있는 인덱스만을 갱신하게 된다. 그렇기 때문에 UPDATE 컬럼이 사용된 인덱스의 개수에 의해 UPDATE 성능은 저하된다.
 
INSERT에 비해 UPDATE는 성능을 저하시키는 항목이 더 적다. 하지만, 동일한 양에 대해 INSERT와 UPDATE를 수행한다면 UPDATE가 성능 저하를 더 많이 발생시키게 된다. 이와 같은 이유는 왜일까? 분명히 성능 저하의 요소는 INSERT가 더 많기 때문에 INSERT가 더 많은 부하를 발생시킨다고 생각하기 쉽다. 이는 로그 기록과 롤백을 위한 로그 기록의 방식 차이 때문이다. INSERT 작업은 로그에 이전 데이터라는 것은 존재하지 않는다.
 
INSERT 작업이 수행된 데이터의 위치 정보만을 가지게 된다면 우리는 언제든지 롤백을 수행할 수 있으며 장애 시 복구도 어렵지 않게 된다. 하지만, UPDATE의 경우에는 이전 데이터의 값이 존재하기 때문에 이전 데이터를 로그에 기록하게 된다. 따라서 로그 기록 및 롤백을 위한 로그 기록에서 UPDATE가 INSERT에 비해 더 많은 데이터를 기록해야 하므로 디스크 I/O의 증가로 UPDATE의 성능은 INSERT의 성능보다 더욱 저하되게 된다.
 
세 번째로 DELETE 작업은 어떠한가? DELETE는 저장되어 있는 데이터를 삭제하는 기능을 수행하게 된다. 위와 같은 DELETE는 아래와 같은 항목들에 의해 성능이 저하된다.
 
·로그 기록
·인덱스의 개수
·롤백을 위한 로그 기록
·디스크 I/O
 
다른 항목은 INSERT 또는 UPDATE와 동일하다. 차이라면 로그 기록 및 롤백을 위한 로그 기록시 삭제되는 데이터의 이전 데이터와 이후 데이터를 모두 기록해야 한다는 것이다. 물론, 롤백을 위한 로그 기록 시에는 이전 데이터의 값과 위치 정보만을 가지게 된다. 결국, 이와 같은 이유로 동일한 양의 데이터를 DELETE하는 경우 INSERT에 비해 더 많은 디스크 I/O가 발생하게 되므로 성능은 저하되게 된다.
 
다양한 성능 저하의 요소를 가지는 DML 작업에서 대용량의 데이터에 대해서 어떤 방식으로 작업을 수행해야만 성능을 보장 받을 수 있겠는가?
 
 
INSERT의 성능 저하 요소를 감소시키자
 
 
일반적으로 DELETE 또는 UPDATE의 경우에는 INDEX의 개수만을 최적화하여 성능을 향상시킬 수 있다. 하지만, INSERT의 경우에는 위와 같은 성능 저하의 요소 중 아래와 같은 요소에 대해 획기적으로 감소시킬 수 있게 된다.
 
·로그 기록
·HWM BUMP UP
·롤백을 위한 로그 기록
 
위와 성능 저하 요소는 우리가 조금만 깊이 있게 고려한다면 최소화 시킬 수 있으며 위의 항목을 최소화 시킨다면 디스크 I/O는 자동으로 감소하게 된다. 그렇다면 어떻게 위의 성능 저하의 요소를 감소시킬 수 있겠는가?
 
첫 번째로 HWM BUMP UP과 롤백을 위한 로그 기록을 감소시키는 방법을 확인해보자. HWM BUMP UP을 제거하기 위해서는 HWM를 이동시키지 않고 데이터를 HWM 뒤에 존재하는 블록에 저장하면 될 것이다. 이와 같다면 롤백 또한 이전 데이터의 정보를 하나 하나 기록하는 것이 아니라 HWM의 위치 정보 하나만을 기록한다면 롤백 수행 시 HWM 위치 뒤에 존재하는 모든 블록을 제거한다면 롤백을 수행한 것과 동일한 현상이 발생할 것이다.
 
결국, HWM를 고정시키고 데이터를 HWM 뒤에 존재하는 블록에 저장시킨다면 HWM BUMP UP과 롤백을 위한 로그 기록에 의해 발생하는 성능 저하는 해결될 수 있을 것이다. 이와 같이 INSERT를 수행하는 방법이 바로 직접 로딩(DIRECT LOADING) 방식이다. 직접 로딩 방식을 사용한다면 HWM 뒤의 블록에 데이터를 저장하게 되므로 두 가지 문제는 모두 해결될 수 있을 것이다. 그렇다면 직접 로딩은 어떻게 사용하는 것인가?
 
·INSERT /*+ APPEND */ …… SELECT ……
 
위와 같이 SELECT를 수행하여 해당 데이터를 테이블에 INSERT하는 경우에 APPEND 힌트를 사용하여 직접 로딩을 수행하게 된다.
 
두 번째로 로그 기록을 확인해 보자. 우리가 테이블에 데이터를 저장하는 경우 일반적으로는 LOGGING 상태이므로 앞서 언급한 모든 로그를 기록하게 된다. 하지만, 직접 로딩(DIRECT LOADING) 기법을 사용하게 된다면 HWM 뒤에 존재하는 블록에 데이터를 저장하게 되므로 별도의 로그를 기록하지 않아도 복구 시 HWM 뒤의 블록에 존재하는 데이터를 제거하면 될 것이다. 이와 같은 이유에서 직접 로딩 방식의 경우에는 로그를 기록하지 않는 NOLOGGING 방식으로 데이터를 저장할 수 있게 된다.
 
결국, 위와 같이 NOLOGGING 상태에서 직접 로딩을 수행한다면 앞서 언급한 3가지의 성능 저하 요소를 대부분 제거할 수 있으며 이로 인해 디스크 I/O는 감소하게 된다. 상황에 따라 다르지만 대용량의 데이터에 대해 NOLOGGING 상태의 직접 로딩은 일반 INSERT에 비해 10배 이상 성능을 향상시킬 수도 있으며 그 이상의 성능 향상을 기대할 수도 있다.
 
 
DELETE와 UPDATE의 성능을 최적화하자
 
 
대용량의 데이터에 대해 DELETE 또는 UPDATE를 수행한다면 엄청난 성능 저하가 발생할 수 있다. DELETE 또는 UPDATE는 INSERT에 비해 더 많은 자원을 사용하게 되며 직접 로딩 또는 NOLOGGING 상태와 같은 방법이 존재하지 않게 된다. 많은 데이터에 대해서는 과거에나 지금이나 성능 저하를 감수할 수 밖에는 없을 것이다. 하지만, 이와 같은 대용량의 DELETE 또는 UPDATE에 대해서도 성능을 최적화 시키는 방법은 존재한다.
 
우리는 데이터를 변경하기 위해서는 항상 UPDATE를 사용해야 한다고 생각하고 데이터를 삭제하기 위해서는 항상 DELETE를 수행해야 한다고 생각한다. 일반적으로 생각한다면 당연한 사실일 것이다. 하지만, 이와 같은 고정 관념으로는 대용량의 데이터에서 더 이상의 성능 향상을 기대할 수 없을 것이다.
 
대용량의 데이터에 대해 UPDATE 또는 DELETE를 수행하는 경우 최적의 성능을 보장 받기 위해서는 기존의 사고 방식에서 벗어나야 할 것이다. 결국, 생각하는 방식의 전환만이 대용량의 데이터에 대해 UPDATE와 DELETE의 성능을 최적화하는 유일한 방법이 될 것이다.
 
대용량의 데이터에 대해 데이터의 변경에 대해 UPDATE로 작업을 수행하지 말고 데이터의 삭제에 대해 DELETE로 작업을 수행하지 말아야 한다. UPDATE는 INSERT로 변경하고 DELETE 또한 INSERT로 변경하는 순간 최적의 성능을 기대할 수 있을 것이다. UPDATE를 INSERT로 DELETE를 INSERT로 수행하는 것이야말로 우리의 기존 고정 관념을 파괴하는 행위일 것이다. 이제는 이와 같은 기존의 고정 관념을 파괴하여 성능을 최적화해야 할 것이다.
 
그렇다면 어떤 이유에서 UPDATE 또는 DELETE 대신 INSERT를 사용해야 하는가? 이유는 간단하다. INSERT는 UPDATE와 DELETE와는 달리 직접 로딩과 NOLOGGING이 가능하기 때문이다. 이와 같은 성능 향상의 요소는 우리에게 엄청난 혜택을 제공하기 때문이다.
 
그렇다면 어떻게 UPDATE를 INSERT로 변경하고 DELETE를 INSERT로 변경할 수 있겠는가? 물론, 데이터 삭제에 INSERT를 사용해야 하기 때문에 작업 절차는 복잡해 질 수 있다. 예를 들어, TEST 테이블의 크기가 100GB이며 그 중 50GB에 해당하는 데이터를 삭제해야 한다고 가정하자. 그렇다면 DELETE를 수행하는 순간 우리는 엄청난 시간을 기다려야 해당 작업을 종료할 수 있을 것이다.
 
DELETE를 INSERT로 변경한다면 어떻게 되겠는가? 우선, TEST 테이블과 동일 구조의 TEST_IMSI 테이블을 생성한 후 TEST 테이블로부터 데이터가 삭제된 후 남게 되는 데이터만을 조회하여 TEST_IMSI 테이블에 INSERT를 수행한다. 해당 작업에는 TEST_IMSI 테이블을 NOLOGGING 상태로 변경한 후 해당 테이블에 직접 로딩을 수행해야 할 것이다. 고성능의 디스크를 사용하는 시스템이라면 1GB에 1분 정동의 INSERT 시간이 소요된다.
 
50GB의 데이터를 INSERT하면 되므로 최적화된다면 50분 정도의 시간이 소요될 것이다. 이 얼마나 빠른 속도인가? 물론, 경우에 따라 병렬 프로세싱을 이용해야 할 수 도 있다. 이와 같이 작업을 수행했다고 모든 것이 종료되는 것은 아니다. TEST 테이블을 TEST_BACKUP으로 이름을 변경하고 TEST_IMSI 테이블을 TEST 테이블로 이름을 변경해야 할 것이다. 물론, 인덱스가 필요하다면 인덱스도 생성해야 할 것이다.
 
이와 같이 작업 절차는 복잡해 지지만 DELETE를 수행하는 것보다는 10배 아니 그 이상의 성능 향상을 기대할 수 있을 것이다. UPDATE의 경우도 이와 다르지 않다. UPDATE 후의 데이터를 임시 테이블에 INSERT를 수행하고 해당 테이블의 이름을 변경한다면 기존 테이블에는 UPDATE 후의 데이터가 저장되므로 INSERT를 이용하여 UPDATE를 대신할 수 있게 된다.
 
이와 같은 방식으로 기존의 방식에서 벗어날 수 있다면 우리는 최적의 성능을 기대할 수 있을 것이다.
 
우리가 가지고 있는 기존의 방식을 버린다는 것은 쉬운 일이 아닐 것이다. 하지만, 더 좋은 방법이 있다면 과감히 새로운 방법을 선택하는 것도 필요할 것이다. 데이터의 갱신과 제거를 UPDATE와 DELETE로 구현하는 것이 아니라 INSERT로 구현한다면 많은 사람들이 의아해 할지도 모른다. 하지만, 분명히 가능한 일이며 이를 통해 우리는 INSERT의 최고의 아키텍쳐인 NOLOGGING과 직접 로딩을 이용할 수 있다는 것을 명심하길 바란다.

제공 : DB포탈사이트 DBguide.net

728x90
728x90

The table that follows summarizes Oracle built-in datatypes. Please refer to the syntax in the preceding sections for the syntactic elements. The codes listed for the datatypes are used internally by Oracle Database. The datatype code of a column or object attribute is returned by the DUMP function.


CodeDatatypeDescription

1

VARCHAR2(size [BYTE |CHAR])

Variable-length character string having maximum length size bytes or characters. Maximum size is 4000 bytes or characters, and minimum is 1 byte or 1 character. You must specify sizefor VARCHAR2.

BYTE indicates that the column will have byte length semantics; CHAR indicates that the column will have character semantics.

1

NVARCHAR2(size)

Variable-length Unicode character string having maximum length size characters. The number of bytes can be up to two times size for AL16UTF16 encoding and three times size for UTF8encoding. Maximum size is determined by the national character set definition, with an upper limit of 4000 bytes. You must specify size for NVARCHAR2.

2

NUMBER[(precision [,scale]])

Number having precision p and scale s. The precision p can range from 1 to 38. The scale s can range from -84 to 127.

8

LONG

Character data of variable length up to 2 gigabytes, or 231 -1 bytes. Provided for backward compatibility.

12

DATE

Valid date range from January 1, 4712 BC to December 31, 9999 AD. The default format is determined explicitly by the NLS_DATE_FORMAT parameter or implicitly by the NLS_TERRITORYparameter. The size is fixed at 7 bytes. This datatype contains the datetime fields YEARMONTHDAYHOURMINUTE, and SECOND. It does not have fractional seconds or a time zone.

21

BINARY_FLOAT

32-bit floating point number. This datatype requires 5 bytes, including the length byte.

22

BINARY_DOUBLE

64-bit floating point number. This datatype requires 9 bytes, including the length byte.

180

TIMESTAMP[(fractional_seconds)]

Year, month, and day values of date, as well as hour, minute, and second values of time, where fractional_seconds_precision is the number of digits in the fractional part of the SECONDdatetime field. Accepted values of fractional_seconds_precision are 0 to 9. The default is 6. The default format is determined explicitly by the NLS_DATE_FORMAT parameter or implicitly by the NLS_TERRITORY parameter. The sizes varies from 7 to 11 bytes, depending on the precision. This datatype contains the datetime fields YEARMONTHDAYHOURMINUTE, and SECOND. It contains fractional seconds but does not have a time zone.

181

TIMESTAMP[(fractional_seconds)] WITH TIME ZONE

All values of TIMESTAMP as well as time zone displacement value, where fractional_seconds_precision is the number of digits in the fractional part of the SECOND datetime field. Accepted values are 0 to 9. The default is 6. The default format is determined explicitly by the NLS_DATE_FORMAT parameter or implicitly by the NLS_TERRITORY parameter. The size is fixed at 13 bytes. This datatype contains the datetime fields YEARMONTHDAYHOURMINUTESECONDTIMEZONE_HOUR, and TIMEZONE_MINUTE. It has fractional seconds and an explicit time zone.

231

TIMESTAMP[(fractional_seconds)] WITH LOCAL TIME ZONE

All values of TIMESTAMP WITH TIME ZONE, with the following exceptions:

  • Data is normalized to the database time zone when it is stored in the database.

  • When the data is retrieved, users see the data in the session time zone.

The default format is determined explicitly by the NLS_DATE_FORMAT parameter or implicitly by the NLS_TERRITORY parameter. The sizes varies from 7 to 11 bytes, depending on the precision.

182

INTERVAL YEAR[(year_precision)] TOMONTH

Stores a period of time in years and months, where year_precision is the number of digits in the YEAR datetime field. Accepted values are 0 to 9. The default is 2. The size is fixed at 5 bytes.

183

INTERVAL DAY[(day_precision)] TOSECOND[(fractional_seconds)]

Stores a period of time in days, hours, minutes, and seconds, where

  • day_precision is the maximum number of digits in the DAY datetime field. Accepted values are 0 to 9. The default is 2.

  • fractional_seconds_precision is the number of digits in the fractional part of the SECOND field. Accepted values are 0 to 9. The default is 6.

The size is fixed at 11 bytes.

23

RAW(size)

Raw binary data of length size bytes. Maximum size is 2000 bytes. You must specify size for a RAW value.

24

LONG RAW

Raw binary data of variable length up to 2 gigabytes.

69

ROWID

Base 64 string representing the unique address of a row in its table. This datatype is primarily for values returned by the ROWID pseudocolumn.

208

UROWID [(size)]

Base 64 string representing the logical address of a row of an index-organized table. The optional size is the size of a column of type UROWID. The maximum size and default is 4000 bytes.

96

CHAR [(size [BYTE |CHAR])]

Fixed-length character data of length size bytes. Maximum size is 2000 bytes or characters. Default and minimum size is 1 byte.

BYTE and CHAR have the same semantics as for VARCHAR2.

96

NCHAR[(size)]

Fixed-length character data of length size characters. The number of bytes can be up to two times size for AL16UTF16 encoding and three times size for UTF8 encoding. Maximum size is determined by the national character set definition, with an upper limit of 2000 bytes. Default and minimum size is 1 character.

112

CLOB

A character large object containing single-byte or multibyte characters. Both fixed-width and variable-width character sets are supported, both using the database character set. Maximum size is (4 gigabytes - 1) * (database block size).

112

NCLOB

A character large object containing Unicode characters. Both fixed-width and variable-width character sets are supported, both using the database national character set. Maximum size is (4 gigabytes - 1) * (database block size). Stores national character set data.

113

BLOB

A binary large object. Maximum size is (4 gigabytes - 1) * (database block size).

114

BFILE

Contains a locator to a large binary file stored outside the database. Enables byte stream I/O access to external LOBs residing on the database server. Maximum size is 4 gigabytes.



url : http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/sql_elements001.htm#i46376

728x90

+ Recent posts