피자아저씨 댁에 다녀왔습니다.

사용자 삽입 이미지

'Photo Album > Family' 카테고리의 다른 글

20080927 무지개 운동회  (0) 2008.09.27
20080915 노떼월드 방문~  (0) 2008.09.15
20080802 여수 소아과~  (0) 2008.08.02
20080801 여수 나들이  (0) 2008.08.01
애니GIF 로 만들어본 산.강.수... 뭐냐 이건..  (0) 2008.07.20
병원에 갔었습니다. 의사의 한마디에 불안해하고 신경쓰는 부모의 맘이란..
이틀동안 세번을 가서 각각 3명의 소아과 의사에게 진찰을 받았습니다. 근데 말이 다 달라요..
여수에서 올라와서 아이들 소아과에 갔었는데..거기도 말이 달라요..
당췌 엄마 아빠는 어쩌라는거냐고..

사용자 삽입 이미지

'Photo Album > Family' 카테고리의 다른 글

20080915 노떼월드 방문~  (0) 2008.09.15
20080807 피자아저씨네 다녀왔어요  (0) 2008.08.07
20080801 여수 나들이  (0) 2008.08.01
애니GIF 로 만들어본 산.강.수... 뭐냐 이건..  (0) 2008.07.20
20080719 피자헛  (0) 2008.07.19
여수 식구들입니다....

사용자 삽입 이미지
사용자 삽입 이미지
휴가를 맞이하여 여수에 다녀왔습니다. 계곡으로 물놀이도 다녀왔습니다.
사용자 삽입 이미지

'Photo Album > Family' 카테고리의 다른 글

20080807 피자아저씨네 다녀왔어요  (0) 2008.08.07
20080802 여수 소아과~  (0) 2008.08.02
애니GIF 로 만들어본 산.강.수... 뭐냐 이건..  (0) 2008.07.20
20080719 피자헛  (0) 2008.07.19
20080708 폰사진  (0) 2008.07.08

뭐 NDSL도 있고 차량용 USB 시거잭도 필요하고 220V콘센트용 USB충전기도 하나 필요해서
닌텐도 충전기 3종 풀세트를 주옥선에서 구입했다..
NDSL 충전기야 그닥 필요한건 아니었는데 기왕이면 다홍치마 뭐 한번에 다 주니..
가끔 산이나 강이에게 필요할수도 있겠다 싶어서... 지른후... 역시... 각자 있어야할 위치로 뿔뿔이 헤쳐모여서 잘 살고 있다..

사용자 삽입 이미지

'Hobby & Joy > Toy Box' 카테고리의 다른 글

닌텐도 Wii  (0) 2008.09.13
IOCELL R5 8G  (0) 2008.08.18
아센코리아 GPS-730  (0) 2008.07.21
퓨전FnC 플레어컴 128bit 블루투스 스테레오 헤드셋 BT-102  (0) 2008.07.19
Microsoft Bluetooth Notebook Mouse 5000  (0) 2008.07.18

사용자 삽입 이미지
휴대폰 바꾸고 오만가지를 지르다 지르다 결국 GPS까지 구입했습니다.
주옥선과 그마켓을 한참 뒤지다가 아센코리아의 GPS-730 과 GPS-740 사이에서 고민하다가..
결국 총알앞에 무릎을 꿇고 로거 기능이 없는 GPS-730 을 구입했습니다.
스스로에게 " 난 로거기능같은거 필요 없어 " 라고 주문을 외우고 자기최면을 한참 건 후에 정신을 차려보니 이미 구매가 끝나 있더군요..
물건은 문제가 없었으나 배송중 KGB 택배... 죽음이더군요... 이건 뭐..

신호는 겁나 잘 잡힙니다.. 뭐 어쨌던 대만족입니다.

사용자 삽입 이미지

사용자 삽입 이미지

사용자 삽입 이미지

사용자 삽입 이미지

사용자 삽입 이미지

'Photo Album > Family' 카테고리의 다른 글

20080802 여수 소아과~  (0) 2008.08.02
20080801 여수 나들이  (0) 2008.08.01
20080719 피자헛  (0) 2008.07.19
20080708 폰사진  (0) 2008.07.08
20080705 호랑이세상에서 물놀이~  (0) 2008.07.05
교회에서 연습이 끝나고 마트에 가기전에..허기를 채우러 다녀왔습니다.
사용자 삽입 이미지

오늘의 장난감은 FusionFNC에서 뗘다 파는 물건... 플레어컴의 BT-102 되겠습니다.
이거 음질을 포기하니 상당히 편하더군요...
음질을 포기하지 않고 편하려면 총알이 턱없이 많이 필요해서.. 포기했습니다.
전 포기가 빠른 남자거든요..

이거 사자마자 다음날 충전하다가 헤드셋이 홀랑 타버렸더랩니다. FusionFnC에 처음 샀던 흰색을 AS 보내고 검정색을 새로 받았습니다. 흰색에 문제가 있는게 아니라 제가 그렇게 선택했더랩니다. 흰색 검정색 모두 써보니 검정색이 귀에 걸고 다니기가 조금 더 무난했습니다.

사용자 삽입 이미지

사용자 삽입 이미지

소프트웨어보다 하드웨어를 더 잘만드는 마소에서 나온 블루투스 노트북마우스입니다.
누구나가 공감하시겠지만 아무리 생각해도 마소는 하드웨어에 더 강한거 같습니다.

사용자 삽입 이미지
사용자 삽입 이미지

결국 블루투스 동글 두개를 질렀습니다.
Class1 짜리 좀 큰넘 하나랑...
휴대하면서 쓸수 있는 Class2 작은넘 하나 해서..두개죠..

둘다 Bluetooth Ver2 에 EDR 2.1 지원입니다. 저전력에 손쉬운 페어링이라고 하지요..
근데...사실 잘 모르겠습니다. 어쨋던 선이 사라지니 좀 정리가 되긴 하는데...
눈에 띄게 확 깔끔하다거나 해진게 없습니다.. 충전용  케이블만 해도 주루룩이라서요..

사용자 삽입 이미지 사용자 삽입 이미지

새 전화기에 쓸려고 주문한 메모리가 왔습니다.

사용자 삽입 이미지

사용자 삽입 이미지
그동안 쭉 써오던 SK를 버리고 LGT로 갈아탔습니다.
무개념 막장 판매자 때문에 LGT는 시작부터 진상 고객이 되어버렸네요.. 암튼 이거 저거 주변기기 모으느라 또 총알은 다 털리게 생겼습니다.
전화기는 싸게 샀는데 왜 돈들어가는건 마찬가지인지..


Slim Bar Type 스마트폰
사용자 삽입 이미지
624Mhz 의 고속 CPU와 Windows Mobile 6.0. 지상파 DMB를 적용하고도 14mm의 슬림사이즈를 구현한 스마트폰입니다. 슬림한 스마트폰으로 LG Telecom의 웹브라우징(PC 인터넷 뷰어)과 멀티미디어 서비스(Qup), 기분존 서비스를 즐겨보세요.


지상파 DMB
사용자 삽입 이미지
지상판 DMB(Digital Multimedia Broadcasting)는 영상/음성 등의 멀티미디어 방송을 기지국을 이용하여 디지털로 제공하는 방송서비스로, 고화질의 영상과 고음질의 음악을 다양한 채널을 통해 언제 어디서나 감상할 수 있습니다. DMB 방송 시청 중 블루투스 스테레오 헤드셋을 통해서 무선으로 DMB방송의 감상이 가능 합니다.


2.8형 대화면 컬러 LCD [터치 스크린 적용]
사용자 삽입 이미지
2.8형 262K Color TFT LCD를 탑재, 대화면의 장점 및 휴대성을 동시에 구현하였으며, 보다 편리한 입력을 위하여 새로운 입력방식인 모아키 입력을 적용해 편리하게 문자를 입력할 수 있습니다. 넓은 화면으로 지상파 DMB 등의 멀티미디어 기능을 즐겨 보세요

진동 터치 기능 적용

사용자 삽입 이미지

스크린 터치시 진동 기능이 제공되어, 스크린 터치가 됐는지 촉감으로 쉽게 알수 있습니다. 진동터치(VIBETONZ) 기능으로 부드러운 진동을 느껴보세요.


블루투스 기능
사용자 삽입 이미지

블루투스 스테레오 헤드셋을 적용하였습니다.



3D 사운드 및 가상 5.1CH 적용
사용자 삽입 이미지
3D 사운드 및 가상5.1CH 가능을 적용(이어폰 장착시만 사용 가능) 보다 생생하고 선명한 음원을 느낄 수 있습니다. 또한 Windows Media Player v10이 기본으로 내장되어 있습니다.


디지털 카메라 기능
사용자 삽입 이미지
200만 화소 카메라가 장착되어 있어 언제 어디서나 원하는 장면을 내 휴대폰에 담을 수 있습니다. 디지털 카메라처럼 사진크기조정, 화질조정, 화이트밸런스조정 등의 기능을 지원하며, QVGA(320X240)사이즈의동영상 촬영이 가능합니다.


블랙 UI 적용
사용자 삽입 이미지

블랙 UI 가능이 적용된 스마트폰입니다. Black 계열의 Flash 그래픽 메뉴를 적용하여 보다 고급스럽고 세련된 화면을 만나실 수 있습니다.


완벽한 멀티태스킹 기능
사용자 삽입 이미지
MP3 구동시에도 다른 기능들을 멀티 태스킹으로 활용할 수 있습니다. 또한 여러 개의 프로그램을 동시에 실행 할 수 있으며 Task Manager를 이용해 원하는 기능을 실행, 중지할 수 있습니다.


다양하고 편리한 파일뷰어 기능
사용자 삽입 이미지
PC로 간편하고 쉽게 파일을 저장, 이동 가능하고 Word Mobile. Excel Mobile, Powerpoint mobile, Picsel를 탑재 MS Office File / PDF / JPG / TEXT 등 각종 파일들의 보기, 편집기능을 지원해 편리함을 더해 줍니다.


영한/한영 사전
사용자 삽입 이미지

이제 무거운 영어사전을 불편하게 들고 다니지 마세요. 영어 학습 도움을 위해 영한/한영 사전을 제공합니다. (CD탑재)


보다 빠르게, 보다 강력하게 고속 CPU 내장
사용자 삽입 이미지

MSM6500(EVDO 지원) 및 624MHz CPU가 내장되어 Application을 보다 빠른 속도로 신나게 즐기실 수 있습니다.


확장성 및 대용량 메모리 지원
사용자 삽입 이미지
Window Mobiel 6.0 (phone edition)을 채택, 다양한 Pocket PC 프로그램과 호환이 가능하고 microSD 카드 슬롯 통해 메모리 확장 사용할 수 있고, 기본 메모리로 256 MB를 제공합니다. (사용자 메모리 약 160MB).


※ 제품의 외관, 사양 등은 제품 개선을 위해 사전예고 없이 변경될 수 있습니다.
※ 상기의 특장점 이미지는 제품의 기능을 이해하기 쉽게 만든 이미지로, 실제 제품 기능 구현과 차이가 있을 수 있습니다.

'Hobby & Joy > Toy Box' 카테고리의 다른 글

블루투스 동글 Billionton Bluetooth mini Dongle,  (0) 2008.07.12
SanDisk MicroSDHC 8G Class2  (0) 2008.07.10
Pandora Mini - Double Cutaway Petite  (0) 2008.06.14
붕가붕가 USB 강아지  (0) 2008.05.29
IKEA TERTIAL Work Lamp  (0) 2008.05.15
휴대폰을 바꾸면서..정리하던중 나오는 ㅎㄷㄷ한 사진및 동영상..
내 전화기는 관리를 했지만 중전의 전화기에는 정체모를 수많은 사진들과 동영상들..

그걸 정리좀 하고 나서 무작위로 올립니다...

후보정 없음. 로테이션 없음. 있는 그대로의 사진....


사용자 삽입 이미지

아침부터 밥을 가볍게 먹어주시고 타이거월드 워터파크에 다녀왔습니다.
캐러비안이나 오션등등 보다... 애덜 데리고 가기에는 훨씬 좋더구만요.. 집에서 가깝기도 하고..

온 식구가 즐겁게 놀다 왔습니다.

사용자 삽입 이미지

'Photo Album > Family' 카테고리의 다른 글

20080719 피자헛  (0) 2008.07.19
20080708 폰사진  (0) 2008.07.08
20080623 애슐리에 간 돼지삼남매  (0) 2008.06.23
20080515 아침 출근전~  (0) 2008.05.15
20080428 일상..  (0) 2008.04.28
애슐리에 갔었습니다. 무쟈게 먹었습니다. 낸 돈이 안아까우리만큼 먹었습니다. 돼지들...

사용자 삽입 이미지

'Photo Album > Family' 카테고리의 다른 글

20080708 폰사진  (0) 2008.07.08
20080705 호랑이세상에서 물놀이~  (0) 2008.07.05
20080515 아침 출근전~  (0) 2008.05.15
20080428 일상..  (0) 2008.04.28
20080420 뺑뺑이 김수~  (0) 2008.04.20

사용자 삽입 이미지
사고싶은 기타가 생겼다..
내꺼 말고 산이꺼..

지금은 아니고... 산이 기타 잘 갈켜놓으면...하나 들려줘야 겠다...

사용자 삽입 이미지

근데 꽃분홍색 말고...검정색을 원해..
사용자 삽입 이미지 사용자 삽입 이미지 사용자 삽입 이미지

'Hobby & Joy > Toy Box' 카테고리의 다른 글

SanDisk MicroSDHC 8G Class2  (0) 2008.07.10
지상파 DMB 스마트폰 "SPH-M4650"  (0) 2008.07.08
붕가붕가 USB 강아지  (0) 2008.05.29
IKEA TERTIAL Work Lamp  (0) 2008.05.15
[Mplayer] 나의 다섯번째 Mp3 플레이어  (0) 2008.04.29
사무실에서 직원들과 얘기하던중...'붕가붕가' 라는 단어가 불쑥 튀어 나왔다..
우리팀 막내인 여직원이 '붕가붕가' 가 뭔뜻이냐고 물어보던중..
네이버에 물어보라는 대답으로 직접적인 설명을 회피하였으나..
직접 찾아본 '붕가붕가' 는 내가 아는 단어 그 이상의 뜻을 내포하고 있었다..

오늘 아침 사무실 직원하나가 들고온 장난감.. 바로 그 붕가붕가 강아지였으니..



간만에 모두 웃었다.. ^^
근데 이거 웃음으로만 끝날 일은 아닌거 같은데..

지금 밖에서 고생하는 모든 사람들에게.. 그 한사람 한사람에게 미안하다고, 함께하지 못해서 미안하다고.. 지금이라도 뛰어나가야 하지만 이미 난 그렇게 할 수 없을만큼 길들여졌다고.. 눈물흘리며 엎드려 사죄하고 싶습니다. 

나만 생각하는 이기심이 아니라.. 지금의 모습을 두눈으로 똑바로 보지못하는 두려움이라고 변명하고 싶습니다. 너무 무서워서.. 내 식구들이 너무 걱정되어서 당장 내 아이들이 너무 걱정되어서.. 라고.. 변명드립니다..

미안합니다...

'Talk About > Dsus4’s Mind' 카테고리의 다른 글

518  (0) 2010.05.18
다시 태어날 수 있다면...  (0) 2009.02.03
블로그!,블로거?,블로깅!  (0) 2007.08.16
정신없는 일상? 일상은 아니지...  (0) 2007.07.05
AweSome God  (0) 2007.05.08
소니 클리에 PEG-NR70V 드라이버 & 핫싱크 프로그램입니다.
간만에 NR70V를 꺼냈는데 드라이버고 뭐고 암것도 없어서..클리앙에 가서 얻어왔슴다..

아침에 일어나서 출근전에 사진을 찍었습니다.
스승의 날이라고 유치원이 쉰다고 하네요..
스승이라...
뉴스에 나오는 선생질하는 직장인보다... 산이강이 유치원 선생님이 더 스승같이 느껴지는 세상입니다.. 어찌될려고 이러는지..

사용자 삽입 이미지

'Photo Album > Family' 카테고리의 다른 글

20080705 호랑이세상에서 물놀이~  (0) 2008.07.05
20080623 애슐리에 간 돼지삼남매  (0) 2008.06.23
20080428 일상..  (0) 2008.04.28
20080420 뺑뺑이 김수~  (0) 2008.04.20
20080418 아침풍경  (0) 2008.04.18

ㄱ시장에서 스탠드를 하나 샀습니다.
IKEA 에서 나온 접이식 스탠드입니다. 클리앙 알구게(라고 쓰고 지름게 라고 읽는다.)에 올라온 걸 보고 참지못해 또 쓱싹 해버렸습니다. 평소 사무실과 집 모두에서 각각 스탠드가 하나씩 필요했는데 일단 써보고 쓸만 하면 하나더 지를 생각입니다.

안에 든 전구가 그냥 백열등인거 같던데...이거 삼파장 머시기를 또 사야하나..

사용자 삽입 이미지

근데 이케아 물건이 심플하면서도 나름대로 맛이 있네요..

그동안 쏠쏠히 온가족(- 여기서 온가족은 아빠,산,강) 이 즐기던 NDSL 충전파츠가 빠그라졌다..
덩달아 MPlayer의 밥줄 USB케이블도 같이 운명을 달리하셨다.

뭐 눈치가 빠른 분들은 상황이 어찌된건지 알고도 남음이 있겠으나... 주절거림으로 내 쓰린 속을 달래고자 떠들어볼라치면..

시간은 지난 주일 야심한 밤중에... 김산이 혼자 방구석에서 끙끙대고 있는걸 중전이 발견했으니, MPlayer 충전용 USB 케이블을 NDSL 충전구멍에 쑤셔넣기를 한참.. 결론은... NDSL의 충전용 파츠가 빠그라져버리는 사고가 발생하고, USB케이블은 앞부분 쇠로 된 단자가 뿌러져버렸당..

결론은...  돈 들어갈일이 생겼다..ㅜ.ㅜ 젠장...

지못미 NDSL...

 뭐 여차저차 해서..앞으로 한달정도는 음악없이 살 뻔 했으나.. 늘 나와 함께하는 지름신께서 새로운 Mp3를 하나 찍어주셨다.
 딱히 구입하려고 마음먹은건 아니었는데, 딱 이틀동안 음악없이 살아보니 그 허전함이 하늘을 찌르는것 같아서 친구넘이 장터에 내놓은 Mplayer 하나를 슥삭 해버렸다.. 이로서 이번달도 긴축재정이다.

사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지


사용자 삽입 이미지

음....100번째는... 산이 장난감... 101번째는 강이 장난감... 102번째는 수 장난감... 뭐 그런건가...
103번째는 중전마마 소유의 Mp3.... 설마...

'Hobby & Joy > Toy Box' 카테고리의 다른 글

붕가붕가 USB 강아지  (0) 2008.05.29
IKEA TERTIAL Work Lamp  (0) 2008.05.15
[ATH-SJ3 WH] 오디오 테크니카 헤드폰  (0) 2008.04.26
ipTime G301 + V104 로 네트웍 세팅 완료  (0) 2008.02.19
KORG TONEWORKS AX3000G  (0) 2008.01.02
일상의 모습입니다.

사용자 삽입 이미지

'Photo Album > Family' 카테고리의 다른 글

20080623 애슐리에 간 돼지삼남매  (0) 2008.06.23
20080515 아침 출근전~  (0) 2008.05.15
20080420 뺑뺑이 김수~  (0) 2008.04.20
20080418 아침풍경  (0) 2008.04.18
20080203 기도하는중~  (0) 2008.02.03

사용자 삽입 이미지

내가 산건 흰색~

헤드폰을 하나 샀습니다.
그동안 쓰던 커널형 이어폰은 망가지고 친구넘에게 갈취한 MX400 은 어디로 갔는지 보이지를 않고 .. 해서 고민하다가 보급형 헤드폰을 하나 사버렸습니다. 그런데.. 헤드폰은 토요일에 도착했으나 Mp3를 금요일에 큰형님 입원해 계시는 병원에 두고 와버렸습니다. 이걸 어째..
현재의 용도는 NDSL에 물려서 듣고 있습니다. ㅠ.ㅠ

착용했을때 귀꾸녕을 폭 덮어주는게 느낌은 좋습니다. 물론 가장 중요한 음질은 아직 잘 모르겠습니다. 좀 더 들어봐야 할듯 합니다..



'Hobby & Joy > Toy Box' 카테고리의 다른 글

IKEA TERTIAL Work Lamp  (0) 2008.05.15
[Mplayer] 나의 다섯번째 Mp3 플레이어  (0) 2008.04.29
ipTime G301 + V104 로 네트웍 세팅 완료  (0) 2008.02.19
KORG TONEWORKS AX3000G  (0) 2008.01.02
샤프전자 MD 수리 일대기...  (0) 2007.01.26
근래에 많은 기업들의 데이터베이스가 대용량화 되면서 이를 효과적으로 관리할 수 있는 방안을 찾는 것이 관리자들의 주요 업무가 됐다. 이를 위한 매우 효과적인 방안 가운데 하나가 파티셔닝이다.

일반적으로 단순한 명령어 위주로만 알려져 있지만 실제 현장에서 접하는 파티셔닝의 효용은 그 이상이다. 익숙한 개념이지만 그동안 제대로 알지 못했던 파티셔닝의 의미와 대표적인 활용 사례를 살펴보자.

필자는 많은 현장 사이트에서 대용량의 가치 있는 데이터들이 놀라운 능력을 보유하고 있는 데이터베이스 안에서 사용자의 무지로 인해 방치돼 있거나 잘못 사용되고 있어 역효과를 일으키는 모습을 많이 보아 왔다. 예를 들어 총 테이블 건수 1억 건이 넘는 상황에서 우리가 어떤 형태로든 건드려야 할 부분이 약 10% 정도라고 할 때 그 테이블 전체를 읽지 않고 1000만 건만 읽을 수 있게 해야 하는 것이 당연하지만 실제로는 그렇지 못한 경우를 많이 보아 왔다.

어떻게 처리해야겠다는 생각도 없이 무조건 명령어(command)부터 날리는 것이다. 그렇다면 필요한 테이블 만을 다루려면 어떻게 해야 할까. 이를 위해 필요한 개념이 바로 테이블 파티셔닝(Table Partitioning)이다.

파티셔닝은 지난 강좌에서 살펴본 사항들과 함께 어떤 자동화된 툴로 절대 해결할 수 없는 부분으로 실제로 어떤 상황에서 파티셔닝이 필요하다고 정형화된 법칙은 없다. 중소 용량의 데이터베이스에서도 상황에 따라 꼭 사용해야 하는 경우가 있고, 초대용량의 경우 파티셔닝을 쓰지 않으면 시스템 자체가 관리되지 않을 수도 있다(필자 역시 컨설팅을 하면서 이 파티셔닝을 이용해 많은 시스템을 효율적으로 운영할 수 있다는 것을 직간접적으로 체험한 바 있다).

그러나 대부분의 파티셔닝 관련 자료들은 형식적으로 파티셔닝의 종류를 나열하고 스크립트 정도를 언급하는 수준이다. 이런 식의 접근은 한계가 명확하다.

오히려 파티셔닝을 올바르게 이용하기 위해서는 먼저 데이터베이스 액세스 방식의 정확한 차이와 장단점 그리고 파티션을 이용한 풀 스캔(full scan)에 대해 정확하게 이해할 필요가 있다. 파티셔닝은 일종의 기능일 뿐이어서 스캔에 대한 정확한 이해없이는 이를 사용할 이유도, 어떻게 사용해야 할지도 전혀 알 수가 없다. 각 스캔 방식의 장단점을 알고 어떤 상황에서 어떤 스캔 방법이 유리한 지를 명확하게 이해해야 그에 대한 보완책으로서 파티셔닝의 개념이 보이기 시작한다.

파티셔닝 세계 입문
대용량 테이블이나 인덱스를 파티셔닝한다는 것은 하나의 Object를 여러 개의 세그먼트로 나눈다는 의미이다. 즉 하나의 테이블이나 인덱스가 동일한 논리적 속성을 가진 여러 개의 단위(partition)로 나누어져 각각이 PCTFREE, PCTUSED, INITRANS, MAXTRANS, TABLESPACE, STORAGE PARAMETER 등 별도의 물리적 속성을 갖는 것이다.

특히 관리해야 할 데이터가 늘어나면 성능과 스토리지 관점에서 문제가 생길 수 있는데, 이를 해결할 수 있는 효율적인 방법 가운데 하나가 곧 파티셔닝이다. 파티셔닝은 보통 다음과 같은 장점을 갖고 있다.

◆ 데이터 액세스시(특히 풀 스캔시) 액세스의 범위를 줄여 성능을 향상시킨다.
◆ 물리적으로 여러 영역으로 파티셔닝해 전체 데이터의 훼손 가능성이 줄어들고 데이터 가용성이 향상된다.
◆ 각 파티션별로 백업, 복구 작업을 할 수 있다.
◆ 테이블의 파티션 단위로 디스크 I/O를 분산해 부하를 줄일 수 있다.

오라클 DBMS에서 제공하는 파티셔닝 방식에는 레인지(range) 파티셔닝, 해시(hash) 파티셔닝, 리스트(list) 파티셔닝, 컴포지트(composite) 파티셔닝(레인지-해시, 레인지-리스트) 등이 있다.

특정 컬럼 값을 기준으로 분할하는 레인지 파티셔닝
레인지 파티셔닝은 어떤 특정 컬럼의 정렬 값을 기준으로 분할하는 것이다. 주로 순차적인(historical) 데이터를 관리하는 테이블에 많이 사용된다. 예를 들면 ‘가입계약’이라는 테이블이 있고 여기에 몇 년 동안의 데이터가 쌓여 있다면, 보통 5년치 데이터만 관리하고 이 가운데 자주 액세스하는 하는 것은 최근 1~2년 정도가 일반적이다.

따라서 이를 년별, 월별로 파티셔닝하고 애플리케이션의 SQL을 조정해 전체 데이터가 아닌 최근 정보를 가지고 있는 파티션만 액세스하도록 하면 전체 데이터베이스의 성능을 향상시킬 수 있다. 일부 사례의 경우 가입계약_1999, 가입계약_2000처럼 월별 또는 년별로 테이블을 따로 만들어 사용하기도 했지만 실제로 쓰는 데 불편한 점이 많고 액세스하는 SQL이 복잡해지는 단점이 있다. 다음은 레인지 파티션을 만드는 DDL(Data Definition Language) 스크립트다.

CREATE TABLE CONTRACT
(I_YYYYMMDD VARCHAR2(8), I_CUSTOMER VARCHAR2(9), …… )
TABLESPACE TBS1
STORAGE (INITIAL 2M NEXT 2M PCTINCREASE 0)
PARTITION BY RANGE (I_YYYYMMDD)
(PARTITION PAR_200307 VALUES LESS THAN (‘20030801’),
PARTITION PAR_200308 VALUES LESS THAN (‘20030901’), …… )

PARTITION BY RANGE (COLUMN_LIST)는 특정 컬럼을 기준으로 파티셔닝을 할 것인지를 결정하는 것이고, VALUES LESS THAN (VALUE_LIST)는 해당 파티션이 어느 범위에 포함될 것인지 상한을 정하는 것이다. PARTITION BY RANGE에 나타나는 COLUMN_LIST를 파티셔닝 컬럼이라고 하며 이 값이 파티셔닝 키를 형성한다.

파티셔닝 컬럼은 결합 인덱스처럼 최대 16개까지 지정할 수 있다. VALUESS LESS THAN에 나타나는 VALUE_LIST는 파티셔닝 컬럼들의 상한 값으로, 여기 지정된 값보다 작은 값만을 저장하겠다는 의미이다. 이런 스크립트에서 지정한 물리적 속성들은 각 파티션들이 생성될 때 개별적으로 물리적 속성을 지정하지 않으면 각 파티션들은 이러한 속성 값을 적용 받게 된다.

오직 성능 향상, 해시 파티셔닝
해시 파티셔닝은 특정 컬럼 값에 해시 함수를 적용해 분할하는 방식으로, 데이터의 관리 목적보다는 성능 향상에 초점을 맞춘 개념이다. 레인지 파티셔닝은 각 범위에 따라 데이터 양이 일정치 않아 분포도가 일정치 않은 단점이 있는데, 해시 파티셔닝을 이런 단점을 보완해 일정한 분포를 가진 파티션으로 나누고, 균등한 분포도를 가질 수 있도록 조율해 병렬 프로세싱으로 성능을 높인다. 실제로 분포도를 정의하기 어려운 테이블을 파티셔닝을 할 때 많이 이용하고 2의 배수 개수로 파티셔닝하는 것이 일반적이다.

해시 파티셔닝으로 구분된 파티션들은 동일한 논리, 물리적 속성을 가지다(단 테이블스페이스(tablespace)는 유일하게 파티션별로 지정할 수 있다). 또한 레인지 파티션과 달리 각 파티션에 지정된 값들을 DBMS가 결정하므로 각 파티션에 어떤 값들이 들어 있는지를 알 수 없다. 그러나 대용량의 분포도가 일정치 않은 테이블을 마이그레이션할 때는 프로그램 병렬 방식과 함께 유용하게 사용할 수 있다. 다음은 해시 파티션을 만드는 DDL 스크립트이다.

CREATE TABLE CONTRACT
( SERIAL NUMBER, CODE VARCHAR2(4), ……)
TABLESPACE TBS1
STORAGE (INITIAL 2M NEXT 2M PCTINCREASE 0)
PARTITION BY HASH(SERIAL)
(PARTITION PAR_HASH_1 TABLESPACE TBS2,
PARTITION PAR_HASH_2 TABLESPACE TBS3, ……)

함께 쓰일 때 더욱 강력한 리스트 파티셔닝
리스트 파티셔닝은 특정 컬럼의 특정 값을 기준으로 파티셔닝을 하는 방식이다. 주로 이질적인(distinct) 값이 많지 않고 분포도가 비슷하며 다양한 SQL의 액세스 패스에서 해당 컬럼의 조건이 많이 들어오는 경우 유용하게 사용된다. 예를 들어 ‘서비스 계약’이라는 테이블이 있고 서비스를 최초 가입한 대리점을 ‘가입 대리점’, 변경사항을 처리한 대리점을 ‘처리 대리점’이라고 한다면 모든 서비스의 가입, 해지, 전환 등의 처리 데이터에는 이 두 대리점이 존재한다. 테이블 구조를 보면 다음과 같다.

CREATE TABLE SERVICE_CONTRACT
(I_YYYYMMDD VARCHAR2(8), I_CUSTOMER VARCHAR2(6),
I_DLR_IND VARCHAR2(2), I_DEALER VARCHAR2(6), ……)

즉 I_DLR_IND(대리점 구분)라는 컬럼이 존재하고 ‘A’일 때는 ‘가입 대리점’, ‘S’일 때는 ‘처리 대리점“이라고 할 때 대부분의 조회 패턴에는 가입 대리점 또는 처리 대리점에 해당하는 값이 들어오기 마련이다. 이럴 때 I_DLR_IND로 리스트 파티셔닝을 한다면 어떨까. 즉 집합의 서브 타입을 분류할 때 리스트 파티션은 매우 유용하다. 지금 예로 든 것은 단편적인 것에 불과하지만 리스트 파티셔닝의 위력은 강력하다. 특히 컴포지트 파티션에서 레인지 파티션과 함께 사용하면 전체 데이터베이스의 성능을 크게 향상시킬수 있다. 다음은 리스트 파티션을 만드는 DDL 스크립트이다.

CREATE TABLE SERVICE_CONTRACT
(I_YYYYMMDD VARCHAR2(8), I_CUSTOMER VARCHAR2(6),
I_DLR_IND VARCHAR2(2), I_DEALER VARCHAR2(6), …….)
TABLESPACE TBS1
STORAGE (INITIAL 2M NEXT 2M PCTINCREASE 0)
PARTITION BY LIST (I_DLR_IND)
(PARTITION PAR_A VALUES (‘A’), PARTITION PAR_S VALUES (‘S’))

PARTITION BY LIST에 나타나는 COLUMN_LIST는 파티셔닝 컬럼으로 파티션 키에 해당하고(단 단일 컬럼만 지정할 수 있다), VALUESS LESS THAN에 나타나는 VALUE_LIST는 파티셔닝 컬럼들의 값이다. 여기에 나타낸 값에 해당하는 행들을 저장하겠다는 의미가 된다.

레인지의 장점을 그대로, 레인지-해시 컴포지트 파티셔닝
레인지-해시 컴포지트 파티셔닝은 레인지 방식을 사용해 데이터를 파티셔닝하고 각각의 파티션 내에서 해시 방식으로 서브 파트셔닝을 하는 방식이다. 서브 파티션이 독립된 세그먼트가 되는 것이 특징으로, 다음과 같은 장점이 있다.

◆ 관리와 성능 등 레인지 파티션의 장점을 그대로 수용한다.
◆ 해시 파티션의 이점인 데이터 균등 배치와 병렬화
◆ 서브 파티션에 특정 테이블스페이스를 지정할 수 있다.
◆ 서브 파티션별로 풀 스캔을 할 수 있어 스캔 범위를 줄여 성능을 향상시킨다.

레인지 파티션에서 해당 테이블이 단지 논리적인 구조이고 실제 데이터는 파티셔닝된 세그먼트에 저장됐던 것처럼 컴포지트 파티션에서도 해당 테이블과 파티셔닝된 테이블은 단지 파티셔닝을 위한 논리적인 구조일 뿐이다. 데이터는 가장 하위에 위치한 서브 파티션 영역에 저장된다. 다음은 레인지-해시 컴포지트 파티션을 생성하는 DDL 스크립트이다. PARTITION BY RANGE (I_YYYYMMDD)에 의해 레인지로 파티션을 한 후 SUBPARTITION BY HASH에 의해 서브 파티셔닝을 수행했음을 알 수 있다.

CREATE TABE TB_RANGE_HASH
(I_YYYYMMDD VARCHAR2(8), I_SERIAL NUMBER, SALE_PRICE NUMBER, ……)
TABLESPACE TBS1
STORAGE (INITIAL 2M NEXT 2M PCTINCREASE 0)
PARTITION BY RANGE (I_YYYYMMDD)
SUBPARTITION BY HASH (I_SERIAL)
(PARTITION SALES_1997 VALUES LESS THAN (‘19980101’)
(SUBPARTITION SALES_1997_Q1 TABLESPACE TBS2,
SUBPARTITION SALES_1997_Q2 TABLESPACE TBS3), ……)

레인지-리스트 컴포지트 파티셔닝
레인지-리스트 컴포지트 파티셔닝은 레인지 방식을 사용해 데이터를 파티셔닝하고 각 파티션 안에서 리스트 방식을 이용해 서브 파티셔닝하는 방식이다(이때 서브 파티션은 독립된 세그먼트가 된다). 레인지-리스트 컴포지트 파티션은 레인지-해시 컴포지트 파티션과 비슷하지만 서브 파티션이 리스트 파티션이라는 점이 다르다. 실제 업무에서는 레인지-해시보다 유용한 면이 많다. 다음은 레인지-리스트 컴포지트 파티션을 생성하는 DDL 스크립트이다.

CREATE TABLE TB_RANGE_LIST (
I_YYYYMMDD VARCHAR2(8), I_AGR_IND VARCHAR2(2), I_DELAER VARCHAR2(6), …….)
TABLESPACE TBS1
STORAGE (INITIAL 2M NEXT 2M PCTINCREASE 0 MAXEXTENTS UNLIMITED)
PARTITION BY RANGE (I_YYYYMMDD)
SUBPARTITION BY LIST (I_AGR_IND)
(PARTITION PAR_1997 VALUES LESS THAN (‘19980101’)
(SUBPARTITION PAR_1997_A VALUES (‘A’), SUBPARTITION PAR_1997_A VALUES (‘S’)),
……)

파티션된 인덱스의 참뜻
‘파티션된 인덱스(partitioned index)’라고 하면 대부분의 개발자들은 로컬 인덱스를 떠올린다. 또한 파티션된 테이블에서만 쓰이는 것으로 생각한다. 그러나 이것은 명백한 오산이다. 파티션된 인덱스는 파티션된 테이블과 별개의 것으로, 단지 많은 상호 연관을 갖고 있을 뿐이다. 파티션된 인덱스는 문자 그대로 인덱스를 파티셔닝한 것으로, 해당 테이블이 파티션된 테이블이든 파티션되지 않은(non-partitioned) 테이블이든 상관없이 만들 수 있다.

예를 들면 ‘EMP’ 테이블의 크기가 상당히 크고 파티션되지 않은 일반 테이블일 경우 다음과 같은 과정을 통해 파티션된 인덱스를 만들 수 있다. 이를 ‘Global Prefixed Partitioned Index’라고 부르는데, 파티션 인덱스와 마찬가지로 대용량 데이터 환경에서 성능을 높이고 관리를 편리하게 하기 위해서다.

CREATE INDEX EMP_IDX1 ON EMP (DEPTNO)
GLOBAL
PARTITION BY RANGE (DEPTNO)
(PARTITION PAR_10 VALUES LESS THAN (‘20’) TABLESPACE TBS1,
PARTITION PAR_20 VALUES LESS THAN (‘30’) TABLESPACE TBS2,
PARTITION PAR_30 VALUES LESS THAN (‘40’) TABLESPACE TBS3,
PARTITION PAR_40 VALUES LESS THAN (‘50’) TABLESPACE TBS4,
PARTITION PAR_MAX VALUES LESS THAN (MAXVALUE) TABLESPACE TBS5)

파티션된 인덱스가 유용한 이유는, 앞서 파티션의 개념에서 설명한 것처럼 하나의 인덱스를 여러 개의 독립적인 물리 속성을 가진 세그먼트로 나누어 생성, 관리할 수 있기 때문이다. 오라클 DBMS에서 제공하는 인덱스는 글로벌/로컬 인덱스와 Prefixed/Non-Prefixed 인덱스로 분류된다.

파티션된 인덱스와 일반 인덱스 사이의 차이점은 파티션 테이블과 일반 테이블의 그것과 동일하다. 인덱스는 인덱스 컬럼과 Rowid 순으로 값이 정렬되는데, 이런 특성은 파티션 인덱스에서도 동일하다. 많은 개발자들이 파티션된 인덱스는 전체 테이블 값이 정렬되지 않는다고 생각하지 하지만 이것은 사실과 다르다. 글로벌 파티션된 인덱스의 경우 테이블에 대해 값 정렬이 보장돼 있으며, 인덱스도 파티션별로 독립적으로 관리할 수 있다. 두 가지 방식의 차이는 <그림 1>과 같다.

사용자 삽입 이미지
<그림 1> 파티션된 인덱스와 파티션되지 않은 인덱스의 차이

파티션되지 않은 인덱스는 하나의 루트(root) 노드에서 리프(leaf) 노드까지 전체적인 밸런스를 유지하는 구조이고, 파티션 인덱스는 파티션 별로 독립적인 루트 노드와 리프 노드를 갖고 있음을 알 수 있다. 따라서 파티션되지 않으면 대용량 테이블에서는 글로벌 인덱스의 깊이(depth)가 매우 깊어질 수 있는 단점이 있다.

반면 파티션된 인덱스는 각 파티션별 깊이가 일반 인덱스의 깊이보다 얕고 인덱스도 파티션 별로 할 수 있어 병렬 프로세싱을 이용한 인덱스 관리에 매우 효과적이다.

그렇다면 글로벌 인덱스와 로컬 인덱스는 어떤 차이가 있는 것일까? 많은 개발자들이 파티션됐는지 여부로 판단하지만 이것은 잘못된 생각이다. 앞서 설명한 것처럼 글로벌 인덱스도 파티셔닝할 수 있으며, 이를 파티션별로 관리할 수도 있다. 글로벌 인덱스와 로컬 인덱스의 가장 큰 차이는 ‘정렬’이다. 즉 글로벌 인덱스는 테이블 전체에 대해 인덱스된 컬럼과 Rowid 순으로 정렬되고, 로컬 인덱스는 해당 파티션 내에서만 인덱스된 컬럼과 Rowid 순으로 정렬된다.

또한 로컬 인덱스는 ‘Local’이라는 말에서 알 수 있듯이 지역적인 인덱스로, 해당 테이블(base table)의 파티션 키로 파티셔닝된 인덱스다. 일반적으로 로컬 인덱스의 구성 컬럼에 반드시 파티션 키가 포함돼야 가능한 것으로 알려져 있지만 로컬 인덱스에는 파티션 키가 포함되어 있지 않아도 사용할 수 있다. 다음 예제를 보자. PACKAGE_DLR_IDX1 인덱스의 구성 컬럼에 테이블 파티션 키인 I_DLR_IND가 포함되지 않아도 검색조건에 I_DLR_IND = ‘C’라는 검색 조건이 있기 때문에 해당 파티션의 로컬 인덱스를 이용하는 것을 알 수 있다.

select
*from PACKAGE_DLR
where i_package = ‘AAA’ and i_dlr_ind = ‘C’
Operation Object Name PStart PStop
SELECT STATEMENT Hint=CHOOSE
TABLE ACCESS BY LOCAL INDEX ROWIDPACKAGE_DLR 3 3
INDEX RANGE SCAN PACKAGE_DLR_IDX 3 3

글로벌 인덱스는 전역적인 인덱스로, 기본적으로는 파티션되지 않은 인덱스이다. 대부분의 개발자들은 글로벌 인덱스를 파티셔닝해 사용할 생각을 하지 못하는데, 대용량 테이블에서 인덱스 관리의 효율성을 높이고 인덱스 검색 성능을 높이기 위해서는 이를 파티셔닝하는 것이 좋다. 글로벌 인덱스는 기본 테이블의 파티션 키와 무관하게 파티셔닝하는 것으로 설사 기본 테이블의 파티션 키로 글로벌 인덱스를 파티셔닝했다고 해도 로컬 인덱스처럼 동일파티셔닝(equipartitioning)된 개념이 아니므로 테이블 DDL시 전체 인덱스를 다시 생성해야 한다.

그렇다면 글로벌 파티션 인덱스의 인덱스 컬럼 값은 어떻게 전체 테이블에 대해 정렬을 보장하는 것일까. 예를 들어 5000만 건의 파티션되지 않은 EMP 테이블을 부서번호에 따라 파티셔닝했다고 가정하면 다음과 같다.

CREATE INDEX EMP_IDX1 ON EMP (DEPTNO)
GLOBAL
PARTITION BY RAGE (DEPTNO)
(PARTITION PAR_10 VALUES LESS THAN (‘20’) TABLESPACE TBS1,
PARTITION PAR_20 VALUES LESS THAN (‘30’) TABLESPACE TBS2,
PARTITION PAR_30 VALUES LESS THAN (‘40’) TABLESPACE TBS3,
PARTITION PAR_40 VALUES LESS THAN (‘50’) TABLESPACE TBS4,
PARTITION PAR_MAX VALUES LESS THAN (‘MAXVALE’) TABLESPACE TBS2,

사용자 삽입 이미지
<그림 2> Global Prefixed Partitioned 인덱스

<그림 2>는 Global Prefixed Partitioned 인덱스의 구조다. Prefixed와 Non-Prefixed는 인덱스 파티셔닝 키가 인덱스의 선두 컬럼으로 오는가 그렇지 않은가의 차이가 있다. <그림 2>에서도 ‘Prefixed’란 인덱스의 파티션 키(DEPTNO)가 인덱스 선두 컬럼(DEPTNO)이 되는 것을 알 수 있다. 글로벌 인덱스의 경우 모든 인덱스 컬럼 값이 정렬돼 있다. 각 인덱스 파티션의 루트 블럭(root block)에 들어가는 값들이 인덱스 파티션에 따라 정렬되기 때문에 자연적으로 리프 블럭(leaf block)에 들어가는 모든 값들도 정렬되는 것이다. 반면 Global Non-Prefixed 인덱스를 파티셔닝하면 레인지 파티셔닝 방식으로만 가능하다. 이것은 정렬 때문인데, 레인지 파티션은 정렬 기능을 이용해 파티셔닝 키 자체를 생성하는데 반해 다른 파티셔닝 방식은 정렬과 상관없이 수행하기 때문이다.

로컬 인덱스는 Prefixed 인덱스와 Non-Prefixed 인덱스를 모두 지원한다. 로컬 인덱스는 기본적으로 현재 테이블의 파티션 키가 인덱스의 파티션 키가 되기 때문에 인덱스 컬럼에 현재 테이블의 파티션 키가 포함되지 않아도 인덱스를 생성할 수 있다. 또한 인덱스 컬럼 값의 정렬이 전체 테이블에 대해 보장된 것도 아니기 때문에 인덱스 파티션 키가 인덱스의 선두 컬럼이 될 필요가 없다. 또한 Non-Partitioned 인덱스이든 파티션 인덱스든 상관없이 인덱스를 이용하고자 할 때는 무조건 인덱스 파티션 키를 조회해야 하는 글로벌 인덱스와 달리 로컬 인덱스는 조회 검색조건에 파티션 키가 들어올 수도 있고 들어오지 않을 수도 있다.

대용량 DB 테이블과 인덱스 전략
파티션 인덱스 전략은 파티션 테이블과 밀접하게 연관되어 수립해야 하지만 여기서는 파티션 인덱스를 위주로 이야기를 풀어본다. 먼저 인덱스 크기에 대한 논의는 기본적으로 테이블보다는 훨씬 작게 생성, 관리하는 것이 원칙이다. 따라서 중소 용량의 데이터베이스 환경에서는 파티션 인덱스의 유용성을 따질 필요가 없다. 단 중소 용량의 데이터 환경일 경우에서도 테이블이 파티셔닝돼 있다면 파티션 인덱스를 고려해야 한다. 또한 기본적으로 파티션되지 않은 인덱스(일반 인덱스) 전략을 기본으로 해 테이블이 파티셔닝 된 경우와 인덱스를 파티셔닝했을 때의 장점을 비교해 보아야 한다.

먼저 테이블 파티션 키가 항상 ‘=’로 들어오는 경우 또는 파티션 범위가 크지 않은 경우에는 로컬 인덱스가 최상이다. 인덱스 컬럼의 순서와 구성은 액세스 패스에 따라 생성하면 되지만 최대한 가볍게 생성하는 것이 좋다. 기본 테이블의 파티션 키는 반드시 포함될 필요가 없으나, 테이블이 레인지 파티션이고 한 파티션 범위 안에서 파티션 키의 분포도가 좋을 경우 이를 포함하는 것을 고려해 볼만하다. 이렇게 하면 각 파티션당 인덱스가 파티션되지 않았을 때보다 가벼워지고 데이터 마이그레이션을 할 때도 테이블 파티션과 인덱스 파티션이 동일하므로 exchange, add, drop, split 등 파티션별 관리도 용이하다.

또한 빠른 응답 시간을 요구하는 환경에서 대용량 파티션 테이블의 조회 조건에 파티션 키가 들어오지 않을 가능성이 있다면 파티션 글로벌 인덱스를 고려해 볼만하다. 이렇게 하면 파티션되지 않은 글로벌 인덱스와 달리 레인지 파티션 별로 인덱스가 가벼워지는 장점이 있고, 레인지 파티션 별로 인덱스 split와 rebuild 명령을 독립적으로 수행할 수 있다. 컬럼 분포도에 따른 파티셔닝이나 민감한(critical)한 상수 레인지에 대해서는 파티션을 독립적으로 생성해 인덱스 크기를 줄임으로써 인덱스 검색 시간을 줄일 수 있는 이점도 있다.

exchange는 파티션된 테이블의 특정 파티션과 파티션되지 않은 일반 테이블 간의 구조를 서로 바꾸는 것으로, 대용량의 파티션된 테이블을 관리하는 데 상당한 효과가 있다. <그림 2>와 같이 데이터가 없는 새로운 데이터 테이블과 데이터가 들어 있는 파티션 2를 exchange하면 파티션 2에 해당하는 디렉토리 정보가 새로운 데이터로 바뀌고 새 테이블 데이터에는 데이터가 들어간다. 이것은 실제 데이터가 이동하는 것이 아니라 데이터를 저장하는 테이블 정보만을 업데이트하는 것이다. 한 가지 주의할 점은 exchange하고자 하는 파티션과 테이블의 구조가 같아야 하고 속성들의 특성도 같아야 한다는 사실이다.
exchange의 기본적인 문법은 다음과 같다.

Alter table Tb_Partition
Exchange partition par_200306
With table Tb_Exchange
(Without validation Including indexes)

사용자 삽입 이미지
<그림 3> 대용량 DB에서 exchange 작업

한편 파티션된 대용량 테이블에 split 함수를 실행하면 많은 시간이 걸린다. 이럴 때 exchange 기능을 이용하면 빠르고 안전하게 작업할 수 있다. <그림 4>에서 보는 것처럼 split를 해야 하는 파티션을 exchange에 의해 빈 공간으로 만든 다음 split을 하고 다시 데이터를 채우기 위해 split하는 것이다. 이렇게 하면 대용량의 데이터라도 매우 빠른 시간내에 split 작업을 수행할 수 있다.

사용자 삽입 이미지
<그림 4> 대용량 DB에서 split 작업

한편 대부분의 DBA들과 개발자들은 동일한 테이블을 생성할 때 create table ~ as select 구문을 이용한다. 대용량의 데이터일 경우 parallel 옵션을 줘 생성하기도 한다. 만약 1억 건의 테이블을 그대로 생성한다고 할 때 어떤 방법이 효과적일까. 이렇게 파티션된 대용량 테이블을 생성할 때는 exchange, program parallel 방법을 사용하는 것이 바람직하다.

사용자 삽입 이미지
<그림 5> 동일 테이블을 만들 때

<그림 5>는 이 과정을 도식화한 것이다. 먼저 생성할 TB_PART_1 테이블의 빈껍데기를 만든다. 대용량의 파티션된 테이블의 파티션 각각을 create table ~ as select 구문의 parallel 옵션을 이용해 각 테이블로 생성한다. 이후 미리 생성해 놓은 TB_PART_1 테이블의 파티션과 만들어 놓은 테이블들을 exchange하는 것이다. 이때 파티션별로 200105.sql, 200106.sql, 200107.sql…… 형식으로 만들어 놓고 이 프로그램들을 동시에 실행하면(program parallel) 극적인 효과를 볼 수 있다.

이번엔 데이터 마이그레이션에 대해 살펴 보자. 원격으로 데이터를 옮겨야 할 때 보통 database link를 이용한다. 네트워크를 통해 데이터를 옮기면 직렬(serial)로 데이터가 이동되므로 속도가 현저하게 떨어지기 때문이다. 따라서 소스 테이블을 파티셔닝하고 해당 파티션을 액세스하는 프로그램을 각각 띄워 병렬 프로세싱을 하게 되면 매우 빠른 속도로 데이터를 옮길 수 있다.

소스 테이블을 파티셔닝할 수 있는 상황이라면 테이블의 분포를 보고 레인지나 리스트 방식으로 파티셔닝할 수 있고, 일정한 분포가 존재하지 않는 테이블이라면 해시 파티셔닝으로 분포도를 고르게 나눈 다음 해당 파티션을 읽는 뷰를 액세스해 데이터를 옮기는 것이 좋다.

예를 들어 다음은 중대형 정도 크기인 약 2700만 건의 회원 테이블을 옮기는 DDL 스크립트다. 앞서 언급한 대로 이를 바로 database link를 이용해 처리하면 네트워크의 속도가 떨어져 엄청난 시간이 소요된다. 그러나 이것을 일반 테이블을 여러 개로 파티션을 나누어서 파티션과 병렬 처리하면 성능이 크게 향상된다. 작업 순서는 다음과 같다.

create table t_cust_hash
storage (initial 5M next 5M pctincrease 0)
partition by hash(mem_no)
(
partition par_hash_1 TABLESPACE TS_DATA,
partition par_hash_2 TABLESPACE TS_DATA,
partition par_hash_3 TABLESPACE TS_DATA,
partition par_hash_4 TABLESPACE TS_DATA,
partition par_hash_6 TABLESPACE TS_DATA,
partition par_hash_7 TABLESPACE TS_DATA,
partition par_hash_8 TABLESPACE TS_DATA,
partition par_hash_9 TABLESPACE TS_DATA,
partition par_hash_10 TABLESPACE TS_DATA,
)
nologging
as
select /*+ parallel(x 10) */ * from t_cust x

이제 다음과 같이 소스 테이블 뷰 생성한 후

create or replace view t_cust_1
as select * from t_cust_hash partition (par_hash_1);

create or replace view t_cust_2
as select * from t_cust_hash partition (par_hash_2);

create or replace view t_cust_3
as select * from t_cust_hash partition (par_hash_3)

……

다음과 같이 프로그램 패러럴(program parallel) 작업을 동시에 실행한다.

T_cust_1.sql
create table t_cust_1
storage (initial 5M next 5M pctincrease 0)
nologging
tablespace njh
as
select /*+ parallel(x 4) */ * from t_cust_1@remote x;

T_cust_2.sql
create table t_cust_2
storage (initial 5M next 5M pctincrease 0)
nologging
tablespace njh
as
select /*+ parallel(x 4) */ * from t_cust_2@remote x

이것은 단적인 예에 지나지 않는다. 활용할 수 있는 사례는 얼마든지 있을 것이다. 한편 인덱스는 전체 데이터에 대해 해당 컬럼의 값으로 정렬하기 때문에 대용량 테이블의 경우 create, rebuild 명령을 실행할 때 많은 시간이 필요하다. 이때 파티션된 인덱스를 만들면 인덱스의 생성과 관리를 더 활용적으로 할 수 있다. 다음은 파티션된 인덱스를 Unusable로 생성한 사례다(로컬/글로벌 파티션된 인덱스).

먼저 파티션 인덱스를 ‘unusable’ 옵션을 이용해 생성한다. 실제 데이터를 정렬해 만드는 것이 아니라 일종의 껍데기를 만드는 과정이다. 이제 앞서 살펴본 병렬 처리를 이용해 여러 파티션을 동시에 rebuild를 하면 대용량 데이터라도 빠른 시간에 인덱스를 생성할 수 있다.

CREATE INDEX EMP_IDX1 ON EMP (DEPTNO)
GLOBAL
PARTITION BY RANGE (DEPTNO)
(PARTITION PAR_10 VALUES LESS THAN (‘20’) TABLESPACE TBS1,
PARTITION PAR_20 VALUES LESS THAN (‘30’) TABLESPACE TBS2,
PARTITION PAR_30 VALUES LESS THAN (‘40’) TABLESPACE TBS3,
PARTITION PAR_40 VALUES LESS THAN (‘50’) TABLESPACE TBS4,
PARTITION PAR_MAX VALUES LESS THAN (MAXVALUE) TABLESPACE TBS5)
UNUSABLE;

이제 파티션별로 index1.sql, index2.sql 등을 독립적으로 병렬 실행한다.

ALTER INDEX EMP_IDX1 REBUILD PARTITION PAR_10 PARALLEL 4; ---‘ index1.sql
ALTER INDEX EMP_IDX1 REBUILD PARTITION PAR_20 PARALLEL 4; ---‘ index2.sql
ALTER INDEX EMP_IDX1 REBUILD PARTITION PAR_30 PARALLEL 4; ---‘ index3.sql
ALTER INDEX EMP_IDX1 REBUILD PARTITION PAR_40 PARALLEL 4; ---‘ index4.sql
ALTER INDEX EMP_IDX1 REBUILD PARTITION PAR_MAX PARALLEL 4; ---‘ index5.sql

지금까지 테이블 파티셔닝에 대해 다뤄봤다. 자동화된 성능관리 툴로 커버할 수 없는 영역을 살펴보고 있으나 가장 중요한 것은 데이터베이스 액세스 개념에 대해 정확하게 이해하는 것이다. 많은 사람들이 파티셔닝을 알고 있지만 정확하게 사용하고 있지 못하는 현실이 아타까울 때가 많다. 그러나 이 점은 역설적으로 파티셔닝의 매력이기도 하다. 노력하는 데이터베이스 관리자 만이 도전해 볼 수 있는 영역이 바로 ‘파티셔닝’ 분야이기 때문이다.

FROM 호석
교회에서 뺑뺑이에 탔습니다.
삐그덕대고 잘 돌아가지도 않지만.. 즐겁습니다.

사용자 삽입 이미지

'Photo Album > Family' 카테고리의 다른 글

20080515 아침 출근전~  (0) 2008.05.15
20080428 일상..  (0) 2008.04.28
20080418 아침풍경  (0) 2008.04.18
20080203 기도하는중~  (0) 2008.02.03
20080202 돈부리  (0) 2008.02.02
사용자 삽입 이미지

'Photo Album > Family' 카테고리의 다른 글

20080428 일상..  (0) 2008.04.28
20080420 뺑뺑이 김수~  (0) 2008.04.20
20080203 기도하는중~  (0) 2008.02.03
20080202 돈부리  (0) 2008.02.02
2008 무지개 재롱발표회  (0) 2008.01.30
Add 메서드

         :   키-항목 쌍을 Dictionary 개체에 추가합니다.

문법    :   object.Add key, item

구성요소

설   명

object

필수적인 요소. 항상 Dictionary 개체의 이름입니다.

key

필수적인 요소. 추가할 item과 연관된 key입니다.

item

필수적인 요소. 추가할 key와 연관된 item입니다.

설명

해당 key가 이미 있으면 오류가 발생합니다.
아래 예제는 Add 메서드 사용법을 보여줍니다:

     Dim d                                                       '변수를 작성합니다.
     Set d = CreateObject("Scripting.Dictionary")
     d.Add "a", "Athens"                                   '키와 항목을 추가합니다.
     d.Add "b", "Belgrade"
     d.Add "c", "Cairo"

- Exists 메서드

        :  Dictionary 개체에 지정한 키가 있으면 True를, 없으면 False를 반환합니다.

문법   :  object.Exists(key)

구성요소

설   명

object

필수적인 요소. 항상 Dictionary 개체의 이름입니다.

key

필수적인 요소. Dictionary 개체에서 찾을 key 값입니다.

설명

아래 예제는 Exists 메서드 사용법을 보여줍니다.
    Function KeyExistsDemo
         Dim d, msg                                           '변수를 작성합니다.
         Set d = CreateObject("Scripting.Dictionary")
         d.Add "a", "Athens"                               '키와 항목을 추가합니다.
         d.Add "b", "Belgrade"
         d.Add "c", "Cairo"
         If d.Exists("c") Then
                  msg = "지정한 키가 있습니다."
         Else
                  msg = "지정한 키가 없습니다."
         End If
         KeyExistsDemo = msg
    End Function

- Items 메서드

        :  Dictionary 개체의 모든 항목이 들어있는 배열을 반환합니다.

문법   :   object.Items
               object는 항상 Dictionary 개체의 이름입니다.

설명

아래 코드에서는 Items 메서드의 사용 방법을 보여줍니다.
       Function DicDemo
              Dim a, d, i, s                                     '변수를 작성합니다.
              Set d = CreateObject("Scripting.Dictionary")
              d.Add "a", "Athens"                           '키와 항목을 추가합니다.
              d.Add "b", "Belgrade"
              d.Add "c", "Cairo"

              a = d.Items                                       '항목을 가져옵니다.
              For i = 0 To d.Count -1                     '배열을 반복합니다.
                     s = s & a(i) & "<BR>"                  '반환 문자열을 작성합니다.
              Next
              DicDemo = s
       End Function

- Keys 메서드

        :   Dictionary 개체에 있는 모든 키를 포함하는 배열을 반환합니다.

문법   :   object.Keys
              object는 항상 Dictionary 개체의 이름입니다.

설명

아래 코드에서는 Keys 메서드의 사용 방법을 보여줍니다.
     Function DicDemo
          Dim a, d, i                                        '변수를 작성합니다.
          Set d = CreateObject("Scripting.Dictionary")
          d.Add "a", "Athens"                         '키와 항목을 추가합니다.
          d.Add "b", "Belgrade"
          d.Add "c", "Cairo"
          a = d.Keys                                     '키를 가져옵니다.
          For i = 0 To d.Count -1                   '배열을 반복합니다.
               s = s & a(i) & "<BR>"                   '결과를 반환합니다.
          Next
          DicDemo = s
     End Function

- Remove 메서드

        : Dictionary 개체에서 키-항목 쌍을 제거합니다.

문법   : object.Remove(key)

구성요소

설   명

object

필수적인 요소. 항상 Dictionary 개체의 이름입니다.

key

필수적인 요소. key 구성 요소는 Dictionary 개체에서 제거할 키-항목 쌍과 연관된 키입니다.

설명

지정된 키-항목 쌍이 없는 경우 오류가 발생합니다.
아래 코드에서는 Remove 메서드의 사용 방법을 보여줍니다.

      Dim a, d                                                 '변수를 작성합니다.
      Set d = CreateObject("Scripting.Dictionary")
      d.Add "a", "Athens"                               '키와 항목을 추가합니다.
      d.Add "b", "Belgrade"
      d.Add "c", "Cairo"
      ...
      a = d.Remove("b")                                  '둘째 쌍을 제거합니다.

- RemoveAll 메서드

        : RemoveAll 메서드는 Dictionary 개체에서 키-항목 쌍을 제거합니다.

문법   : object.RemoveAll
            object는 항상 Dictionary 개체의 이름입니다.

설명

아래 코드에서는 RemoveAll 메서드의 사용 방법을 보여줍니다.
       Dim a, d, i                         '변수를 작성합니다.
       Set d = CreateObject("Scripting.Dictionary")
       d.Add "a", "Athens"             '키와 항목을 추가합니다.
       d.Add "b", "Belgrade"
       d.Add "c", "Cairo"
       ...
       a = d.RemoveAll             '사전을 지웁니다. 

'Source Storage > Programming' 카테고리의 다른 글

Microsoft Log Parser 2.2  (0) 2008.03.28
Windows Server 2008 Release  (0) 2007.10.02
JavaScript String Object  (0) 2007.07.31
날이면 날마다 까먹는 정규식 구성요소 (RegExp)  (0) 2007.04.18
HTML 특수문자 코드표  (0) 2007.03.21

+ Recent posts