LOB SEGMENT 생성 GUIDE(LOB column)
parameter에 대한 적절한 설정은 좋은 performance를 내는 데 중요한 요인이 된다.
이들 parameter에 대한 자세한 이해를 통해 효과적인 lob segment를 생성할 수 있다.
참고로 lob에 대한 자세한 정보를 보려면 dba/all/user_lobs를 조회하면 알 수 있다.
/*****************************************************************************************************
*****************************************************************************************************/
CREATE TABLE demolob ( A NUMBER, B CLOB )
STORAGE (INITIAL 256 NEXT 256)
TABLESPACE user_data
LOB(b) STORE AS demolob_seg (
TABLESPACE lob_tb
STORAGE (INITIAL 6144 NEXT 6144)
CHUNK 4
PCTVERSION 20
NOCACHE LOGGING
ENABLE STORAGE IN ROW
INDEX demolob_idx (
TABLESPACE lob_tb
STORAGE ( INITIAL 256 NEXT 256 )
)
);
1) TABLESPACE와 storage parameter
- lob, lob index에 대한 tablespace를 지정하지 않는 경우, 해당 table이 저장되는 tablespace에 같이 저장되게 된다.
lob 컬럼, lob index, table 에 대해 tablespace를 각기 지정하는 것이 contention을 줄일 수 있어 보다 효과적이다. (최소한 lob 컬럼과 다른 컬럼들을 구분하여 별개의 tablespace에 저장하도록 지정하는 것이 바람직하다.)
- lob index는 lob 컬럼의 내부적 저장 위치를 연결시켜주는 indicator를 저장한 index이다.
default로 제공받는 index명은 이해하기 어렵기 때문에 lob index명을 지정하여 사용하는 것이 편하다.
- lob index에 대한 parameter 변경은 alter index문을 이용하지 않고, alter table문을 이용하여야 한다. 단, index명을 바꿀
수는 없다.
2) PCTVERSION
- 데이타를 변경할때는 read consistency를 위해 undo 정보를 저장할 필요가 있다.
그러나 LOB 데이타인 경우, 그 크기가 크기때문에 undo 정보 유지하기에는 많은 어려움이 따르기 때문에,
대신에 old version 데이타를 유지하는 방법으로 read consistency를 제공하고 있다.
pctversion은 old version lob data가 차지하는 percentage를 의미한다.
예를들어 default value가(10) 적용되었다면, 새로운 lob data가 old version의 10%가 저장될때 까지는 old version을 간직
하고 있다가, 이 이상 크기가 되면 바로 old version data를 reclaim하고, 이 space를 재사용 즉, overwrite 하게 된다.
- pctversion을 큰 값을 지정한 경우, old version을 저장하기 위해 보다 많은 space가 필요하게 된다.
하지만 update가 많은 작업인 경우에는 이 값을 높게 잡아 다음과 같은 에러를 피할 수 있을 것이다.
ORA-01555: snapshot too old: rollback segment number with name "" too small
ORA-22924: snapshot too old
- 만약 lob data가 read-only인 경우라면, pctversion은 0으로 설정할 수 있다.
* 읽기 요청이 많으면서 동시에 LOB 변경(20% 이상)
* 읽기 요청이 대부분이며 변경이 거의 없음(5% 이하)
- pctversion 변경
SQL> ALTER TABLE demolob MODIFY LOB(b) (PCTVERSION 10);
3) CACHE/NOCACHE
- 자주 access되는 경우라면, cache를 선택하여 사용한다. default는 nocache이다.
- in-line lob은 영향을 받지 않는다. 즉, in-line lob은 다른 데이타와 마찬가지로 buffer cache에서 바로 읽혀지기 때문이다.
- CACHE_SIZE_THRESHOLD limit이 적용되지 않기 때문에 cache할 때는 주의해야 한다.
- cache/nocache 변경
SQL> ALTER TABLE demolob MODIFY LOB (b) ( CACHE/NOCACHE );
4) CHUNK(디폴트 block size)
- lob data를 access하는 단위로써, db_block_size의 배수로 설정한다.
lob 데이타가 저장될 initial extent, next extent는 chunk의 배수로 설정하는 것이 좋다.
만약 db_block_buffer가 2K이고, chunk를 3K로 설정했다면 chunk는 4K로 조정 되어 적용된다.
- chunk는 in-line lob에는 영향을 주지 않고, out-line lob에만 영향을 준다.
예를들어 chuk를 32K로 설정하고, disable storage in row를 설정했다면 1K의 데이타를 저장할때도 32K가 lob segment에
할당된다.
- lob table이 생성된 이후에는 변경할 수 없다.
5) LOGGING/NO LOGGING
- redo 정보를 생성할 것인지 여부를 결정하는 parameter이다.
- cache option을 사용하는 경우는 무조건 logging을 의미한다.
- logging, nologging에 상관 없이 undo 정보는 lob index에 대해서만 생성되고고, lob 데이타에 대해서는 생성하지 않는다.
- logging인 경우는 redo 정보를 생성하고, bulk load나 대량의 insert를 하는 경우 nologging을 설정하여 redo 정보를 생성
하지 않도록 할 수 있다.
- logging/no logging 변경
SQL> ALTER TABLE demolob MODIFY LOB(b) (NOCACHE NOLOGGING);
6) ENABLE/DISABLE STORAGE IN ROW
- 4k 이하의 data를 in-line에 저장할 지 여부를 결정한다.
- enable인 경우 (default)
4k 이하의 lob은 in-line으로, 즉 테이블에 저장하고, 4k 보다 큰 경우에는 out-line 즉, lob segment에 저장된다.
이때 4K는 control 정보를 포함한 크기로써, 실제 in-line으로 저장할 수 있는 최대 크기는 3964 byte이다.
4K 이상의 데이타는 lob segment에 저장되지만, 36 - 84 bytes의 information 정보는 in-line에 남게 된다.
- disable인 경우
모든 datas는 out-line으로 저장된다. 20 byte lob locator만 in-line으로 저장되어 lob index에서 해당 lob block을 찾을 수
있도록 해준다.
- in-line lob인 경우에는 다른 데이타 타입처럼 REDO, UNDO 정보가 기록된다. 그러나 out-line인 경우에는 column locator
와 LOB INDEX가 변경되는 경우에만 UNDO 정보를 기록한다. 즉, lob segment에 대해서는 undo 정보를 만들지 않는다.
- lob 컬럼에 대한 access가 많지 않은 경우는 disable을 설정하는 것이 바람직하다. High Water Mark를 작게 유지될 수 있기 때문에 특히, full table scan을 자주 하는 table인 경우 유용하다.
- lob table이 생성된 이후에는 변경할 수 없다.
<LOB 생성시 주의사항>
LOB은 데이터의 속성상, 다른 데이터타입에는 없는 다양한 옵션들이 존재한다.
부주의하게 사용할 경우 많은 성능문제를 야기할 수 있다. LOB 생성시 다음과 같은 사항들에 주의해야 한다.
1. enable storage in row 옵션을 사용하는 경우 4000 bytes 보다 작은 LOB 데이터는 로우와 같은 블록에 저장된다.
따라서 Row chaining을 유발할 가능성이 높다.
4000 bytes보다 큰 LOB 데이터는 disable storage in row 옵션을 사용한 것과 같은 효과가 있다.
LOB 데이터의 크기를 고려하여 만일 Row chaining이 발생할 가능성이 높다고 판단되면 disable storage in row 옵션을
사용하는 것이 좋다.
로우와 같은 블록에 저장되는 LOB 데이터를 In-line LOB이라고 부르며, LOB 세그먼트에 저장되는 경우에는 Out-of-line
LOB이라고 부른다.
2. disable storage in row 옵션을 사용하는 경우 LOB 데이터는 별도의 LOB 세그먼트에 저장되며 Row 내에는 20 bytes의
LOB Locator 정보만 저장된다. 이 경우 언두 데이터는 LOB Locator에 대해서만 생성된다. LOB 데이터에 대한 실제적인
언두 정보는 언두 테이블스페이스에 저장되지 않고 같은 LOB 세그먼트 내에 저장됨에 유의해야 한다.
LOB 세그먼트의 언두는 PCTVERSION 옵션에 의해 제어되는데, 가령 PCTVERSION이 50이면 LOB Segment의 공간 중 50%가 언두 정보를 저장하는데 사용된다.
따라서 PCTVERSION을 낮게 주는 경우 예기치 않은 ORA-01555 : snapshot too old 에러가 생길 수 있다.
LOB 세그먼트의 언두 영역 부족에 따른 snapshot too old 에러의 경우 rollback segment name이 공백으로 나온다.
PCTVERSION이 너무 작으면 ORA-01555 에러가 발생할 확률이 높아지고, PTCVERSION이 너무 높으면 공간의 낭비가
심해진다.
이 문제를 해결하는 방법은 일반 롤백 세그먼트에서의 ORA-01555 에러의 경우와 동일하다.
PCTVERSION을 적절히 유지하고 불필요한 커밋을 줄인다. LOB 세그먼트의 확장공간을 적절히 확보해주는 것도 중요하다.
3. CACHE / NOCACHE, LOGGING / NOLOGGING : 만일 LOB 데이터의 크기가 크고 자주 액세스되지 않거나, 무작위적으로
액세스된다면 NOCACHE 옵션을 사용하는 것이 바람직하다. NOCACHE 옵션을 사용하는 경우 리두를 생성할 지의 여부도 지정할 수 있다.
만일 반드시 복구가 될 필요가 없는 데이터라면 Nologging 옵션을 사용함으로써 성능개선효과를 얻을 수 있다. CACHE
옵션을 사용하는 경우에는 반드시 Logging 속성을 지니게 된다. NOCACHE 옵션을 사용하는 경우 버퍼 캐시를 경유하지
않기 때문에 direct path read(lob), direct path write(lob) 이벤트를 대기하게 된다. 하지만 CACHE 옵션을 사용하는 경우에
는 버퍼 캐시를 경유하기 때문에 db file sequential read 와 latch: cache buffers chains 대기를 유발할 수 있다.
4. 청크(chunk)의 크기 : Out-of-line LOB인 경우 청크 단위로 LOB 데이터를 저장하게 된다.
큰 청크 사이즈의 문제는 공간이 낭비될 가능성이 높다는 것이다. 만일 청크가 8K로 되어있는데, 1K 크기의 LOB 데이터가 삽입된다면 나머지 7K의 공간은 사용할 수 없게 된다. 따라서 청크 사이즈를 결정할 때는 대상이 되는 LOB 데이터의 크기 를 고려해서 결정해야 한다.
청크의 크기 단위는 기본적으로 블록 사이즈의 배수가 된다.
만일 블록 사이즈가 8K인 경우 청크의 크기를 5000 bytes로 주면 오라클은 암묵적으로 8192 bytes로 변환한다. 청크의
크기를 지나치게 작게 하는 경우에는 연속적으로 청크를 할당받는 과정에서 오버헤드가 발생하게 된다.