<?xml version="1.0" encoding="utf-8" ?>
<?xml-stylesheet href="http://rss.egloos.com/style/blog.xsl" type="text/xsl" media="screen"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
	<title>오서비네 이글루</title>
	<link>http://altibase.egloos.com</link>
	<description>Lazy 코더 ( 1999 ~ )

&quot; 대부분의 글들은 다른 분의 글을 인용, 펌 한 글입니다. 나름대로 출처를 표시하겠지만, 불펌문제가 있다면 덧글 부탁합니다.&quot;</description>
	<language>ko</language>
	<pubDate>Sun, 19 Apr 2009 16:30:50 GMT</pubDate>
	<generator>Egloos</generator>
	<image>
		<title>오서비네 이글루</title>
		<url>http://pds5.egloos.com/logo/200706/18/69/e0040769.jpg</url>
		<link>http://altibase.egloos.com</link>
		<width>80</width>
		<height>106</height>
		<description>Lazy 코더 ( 1999 ~ )

&quot; 대부분의 글들은 다른 분의 글을 인용, 펌 한 글입니다. 나름대로 출처를 표시하겠지만, 불펌문제가 있다면 덧글 부탁합니다.&quot;</description>
	</image>
  	<item>
		<title><![CDATA[ [펌] 이클립스  ]]> </title>
		<link>http://altibase.egloos.com/2327708</link>
		<guid>http://altibase.egloos.com/2327708</guid>
		<description>
			<![CDATA[ 
  <br />
@@ http://www.sjava.net/28<br />
<div class="titleWrap">					<h2><a href="http://www.sjava.net/28">eclipse 에서 확장자 인식 추가..</a></h2>					<div class="underTitle">						<span class="category"><a href="http://www.sjava.net/category/Tools">Tools</a></span>						<span class="date">Posted at 2008/04/22 09:45</span>					</div>									</div><!--close titleWrap-->													<span style="font-family: tahoma,arial,helvetica,sans-serif;">보통 파일에 대한 인식은 확장자를 기반으로 하고 있다..</span><br style="font-family: tahoma,arial,helvetica,sans-serif;"><span style="font-family: tahoma,arial,helvetica,sans-serif;">하지만, 웹을 통한 서비스는 설정을 통해서 확장자가 다른 파일로 웹 어플리케이션으로 인식할 수 있다..</span><br style="font-family: tahoma,arial,helvetica,sans-serif;"><br style="font-family: tahoma,arial,helvetica,sans-serif;"><span style="font-family: tahoma,arial,helvetica,sans-serif;">위의 상황에 따라서 만약<span id="callbacknestwwwsjavanet281579" style="width: 1px; height: 1px; float: right;"><embed allowscriptaccess="always" id="bootstrapperwwwsjavanet281579" src="http://www.sjava.net/plugin/CallBack_bootstrapperSrc?nil_profile=tistory&amp;nil_type=copied_post" wmode="transparent" type="application/x-shockwave-flash" enablecontextmenu="false" flashvars="&amp;callbackId=wwwsjavanet281579&amp;host=http://www.sjava.net&amp;embedCodeSrc=http%3A%2F%2Fwww.sjava.net%2Fplugin%2FCallBack_bootstrapper%3F%26src%3Dhttp%3A%2F%2Fcfs.tistory.com%2Fblog%2Fplugins%2FCallBack%2Fcallback%26id%3D28%26callbackId%3Dwwwsjavanet281579%26destDocId%3Dcallbacknestwwwsjavanet281579%26host%3Dhttp%3A%2F%2Fwww.sjava.net%26float%3Dleft" swliveconnect="true" width="1" height="1"></span> .xxx라는 확장자로 .jsp와 동일한 서비스를 하려고 이클립스에서 </span><br style="font-family: tahoma,arial,helvetica,sans-serif;"><span style="font-family: tahoma,arial,helvetica,sans-serif;">Windows -&gt; Preferences -&gt; General -&gt; Content Types -&gt; Text 밑에 JSP 를 클릭해서 원하는 확장자를 Add 시켜 주면 됩니다. </span><br />
			 ]]> 
		</description>
		<category>java</category>

		<comments>http://altibase.egloos.com/2327708#comments</comments>
		<pubDate>Sun, 19 Apr 2009 16:30:50 GMT</pubDate>
		<dc:creator>오서비네</dc:creator>
	</item>
	<item>
		<title><![CDATA[ [펌] 자동화 툴로 채울 수 없는 DB 성능관리 2% ]]> </title>
		<link>http://altibase.egloos.com/2308312</link>
		<guid>http://altibase.egloos.com/2308312</guid>
		<description>
			<![CDATA[ 
  unusable 상태로 index 를 모두 만든후 개별로 rebuild 한다.<br />
<br />
-----------------<br />
<br />
From : http://ceusee.springnote.com/pages/510466<br />
<br />
<br />
<div class="page-title"><h1 id="pageTitle">파티셔닝 테이블</h1><div class="write-button"><div class="RoundButton style-writebutton"><div class="RI1"><div class="RI2"><div class="RI3"><div class="RI4"><a class="common-button style-writebutton" onclick="" href="http://www.springnote.com/session/new?return_to=http%3A%2F%2Fceusee.springnote.com%2Fpages%2F510466%3Fedit%3D1">편집하기</a></div></div></div></div></div> </div></div><div class="content-container" id="contentContainer"><div class="content xhtmlEditorBody readonlyContentBody"><p>&nbsp;</p><h2 class="title2">자동화 툴로 채울 수 없는 DB 성능관리 2% 2</h2><blockquote><blockquote><p class="title1" style="text-align: right;">테이블 파티셔닝의 재발견</p><p class="author" style="text-align: right;">남준현 |데이터베이스 모델링, 튜닝 전문 컨설턴트</p></blockquote><p class="author">&nbsp;</p><p class="contentsbox">기업들의 데이터베이스가 대용량화 되면서 이를 효과적으로 관리할 수 있는 방안을 찾는 것이 관리자들의 주요 업무가 됐다. 이를 위한 매우 효과적인 방안 가운데 하나가 파티셔닝이다. 일반적으로 단순한 명령어 위주로만 알려져 있지만 실제 현장에서 접하는 파티셔닝의 효용은 그 이상이다. 익숙한 개념이지만 그동안 제대로 알지 못했던 파티셔닝의 의미와 대표적인 활용 사례를 살펴보자.</p></blockquote><p class="contentsbox">&nbsp;</p><p>필자는 많은 현장 사이트에서 대용량의 가치있는 데이터들이 놀라운 능력을 보유하고 있는 데이터베이스 안에서 사용자의 무지로 인해 방치돼 있거나 잘못 사용되고 있어 역효과를 일으키는 모습을 많이 보아 왔다. 예를 들어 총 테이블 건수 1억 건이 넘는 상황에서 우리가 어떤 형태로든 건드려야 할 부분이 약 10% 정도라고 할 때 그 테이블 전체를 읽지 않고 1000만 건만 읽을 수 있게 해야 하는 것이 당연하지만 실제로는 그렇지 못한 경우를 많이 봐 왔다. 어떻게 처리해야겠다는 생각도 없이 무조건 명령어(command)부터 날리는 것이다. 그렇다면 필요한 테이블 만을 다루려면 어떻게 해야 할까. 이를 위해 필요한 개념이 바로 테이블 파티셔닝(Table Parti tioning)이다.</p><p>파티셔닝은 지난 강좌에서 살펴본 사항들과 함께 어떤 자동화된 툴로도 해결할 수 없는 부분으로 실제로 어떤 상황에서 파티셔닝이 필요하다고 정형화된 법칙은 없다. 중소 용량의 데이터베이스에서도 상황에 따라 꼭 사용해야 하는 경우가 있고, 초대용량의 경우 파티셔닝을 쓰지 않으면 시스템 자체가 관리되지 않을 수도 있다(필자 역시 컨설팅을 하면서 파티셔닝을 이용해 많은 시스템을 효율적으로 운영할 수 있다는 것을 직간접적으로 체험한 바 있다).</p><p>그러나 대부분의 파티셔닝 관련 자료들은 형식적으로 파티셔닝의 종류를 나열하고 스크립트 정도를 언급하는 수준이다. 이런 식의 접근은 한계가 명확하다. 오히려 파티셔닝을 올바르게 이용하기 위해서는 먼저 데이터베이스 액세스 방식의 정확한 차이와 장단점 그리고 파티션을 이용한 풀 스캔(full scan)에 대해 정확하게 이해할 필요가 있다. 파티셔닝은 일종의 기능일 뿐이어서 스캔에 대한 정확한 이해없이는 이를 사용할 이유도, 어떻게 사용해야 할지도 전혀 알 수가 없다. 각 스캔 방식의 장단점을 알고 어떤 상황에서 어떤 스캔 방법이 유리한 지를 명확하게 이해해야 그에 대한 보완책으로서 파티셔닝의 가치가 보이기 시작한다.</p><h3 class="sub1">파티셔닝 세계 입문</h3><p>대용량 테이블이나 인덱스를 파티셔닝한다는 것은 하나의 Object를 여러 개의 세그먼트로 나눈다는 의미이다. 즉 하나의 테이블이나 인덱스가 동일한 논리적 속성을 가진 여러 개의 단위(partition)로 나누어져 각각이 PCTFREE, PCTUSED, INITRANS, MAXTRANS, TABLESPACE, STORAGE PARAMETER 등 별도의 물리적 속성을 갖는 것이다. 특히 관리해야 할 데이터가 늘어나면 성능과 스토리지 관점에서 문제가 생길 수 있는데, 이를 해결할 수 있는 효율적인 방법 가운데 하나가 곧 파티셔닝이다. 파티셔닝은 보통 다음과 같은 장점을 갖고 있다.</p><p class="sourcebox">◆ 데이터 액세스시(특히 풀 스캔시) 액세스의 범위를 줄여 성능을 향상시킨다.<br />
◆ 물리적으로 여러 영역으로 파티셔닝해 전체 데이터의 훼손 가능성이 줄어들고 데이터 가용성이 향상된다.<br />
◆ 각 파티션별로 백업, 복구 작업을 할 수 있다.<br />
◆ 테이블의 파티션 단위로 디스크 I/O를 분산해 부하를 줄일 수 있다.</p><p>오라클 DBMS에서 제공하는 파티셔닝 방식에는 레인지(range) 파티셔닝, 해시(hash) 파티셔닝, 리스트(list) 파티셔닝, 컴포지트(composite) 파티셔닝(레인지-해시, 레인지-리스트) 등이 있다.</p><p>&nbsp;</p><h3>특정 컬럼 값을 기준으로 분할하는 레인지 파티셔닝</h3><p>레인지 파티셔닝은 어떤 특정 컬럼의 정렬 값을 기준으로 분할하는 것이다. 주로 순차적인(historical) 데이터를 관리하는 테이블에 많이 사용된다. 예를 들면 ‘가입계약’이라는 테이블이 있고 여기에 몇 년 동안의 데이터가 쌓여 있다면, 보통 5년치 데이터만 관리하고 이 가운데 자주 액세스하는 하는 것은 최근 1~2년 정도가 일반적이다. 따라서 이를 년별, 월별로 파티셔닝하고 애플리케이션의 SQL을 조정해 전체 데이터가 아닌 최근 정보를 가지고 있는 파티션만 액세스하도록 하면 전체 데이터베이스의 성능을 향상시킬 수 있다. 일부 기업의 경우 가입계약_1999, 가입계약_2000처럼 월별 또는 년별로 테이블을 따로 만들어 사용하기도 하지만 실제로 쓰는데 불편한 점이 많고 액세스하는 SQL이 복잡해지는 단점이 있다. 다음은 레인지 파티션을 만드는 DDL(Data Definition Language) 스크립트다.</p><pre class="sourcebox">          CREATE TABLE CONTRACT<br />
          <br />
           (I_YYYYMMDD VARCHAR2(8), I_CUSTOMER VARCHAR2(9), …… )<br />
          TABLESPACE TBS1<br />
          STORAGE (INITIAL 2M NEXT 2M PCTINCREASE 0)<br />
          <br />
           PARTITION BY RANGE (I_YYYYMMDD)<br />
          <br />
           (PARTITION PAR_200307 VALUES LESS THAN (‘20030801’),<br />
          <br />
           PARTITION PAR_200308 VALUES LESS THAN (‘20030901’), …… )<br />
          </pre><p>PARTITION BY RANGE (COLUMN_LIST)는 특정 컬럼을 기준으로 파티셔닝할 것인지를 결정하는 것이고, VALUES LESS THAN (VALUE_LIST)는 해당 파티션이 어느 범위에 포함될 것인지 상한을 정하는 것이다. PARTITION BY RANGE에 나타나는 COLUMN_LIST를 파티셔닝 컬럼이라고 하며 이 값이 파티셔닝 키를 형성한다. 파티셔닝 컬럼은 결합 인덱스처럼 최대 16개까지 지정할 수 있다. VALUESS LESS THAN에 나타나는 VALUE_LIST는 파티셔닝 컬럼들의 상한 값으로, 여기 지정된 값보다 작은 값만을 저장하겠다는 의미이다. 이런 스크립트에서 지정한 물리적 속성들은 각 파티션들이 생성될 때 개별적으로 물리적 속성을 지정하지 않으면 각 파티션들은 이러한 속성 값을 적용받게 된다.</p><h3 class="sub1">오직 성능 향상, 해시 파티셔닝</h3><p>해시 파티셔닝은 특정 컬럼 값에 해시 함수를 적용해 분할하는 방식으로, 데이터의 관리보다는 성능 향상에 초점을 맞춘 개념이다. 레인지 파티셔닝은 각 범위에 따라 데이터 양이 달라 분포도가 일정치 않은 단점이 있는데, 해시 파티셔닝은 이런 단점을 보완해 일정한 분포를 가진 파티션으로 나누고, 균등한 분포도를 가질 수 있도록 조율해 병렬 프로세싱으로 성능을 높인다. 실제로 분포도를 정의하기 어려운 테이블을 파티셔닝을 할 때 많이 이용하고 2의 배수 개수로 파티셔닝하는 것이 일반적이다. 해시 파티셔닝으로 구분된 파티션들은 동일한 논리, 물리적 속성을 가진다(단 테이블스페이스(tablespace)는 유일하게 파티션별로 지정할 수 있다). 또한 레인지 파티션과 달리 각 파티션에 지정된 값들을 DBMS가 결정하므로 각 파티션에 어떤 값들이 들어 있는지 알 수 없다. 그러나 대용량의 분포도가 일정치 않은 테이블을 마이그레이션할 때는 프로그램 병렬 방식과 함께 유용하게 사용할 수 있다. 다음은 해시 파티션을 만드는 DDL 스크립트이다.</p><pre class="sourcebox">          CREATE TABLE CONTRACT<br />
          <br />
           ( SERIAL NUMBER, CODE VARCHAR2(4), ……)<br />
          TABLESPACE TBS1<br />
          STORAGE (INITIAL 2M NEXT 2M PCTINCREASE 0)<br />
          PARTITION BY HASH(SERIAL)<br />
          <br />
           (PARTITION PAR_HASH_1 TABLESPACE TBS2,<br />
          <br />
           PARTITION PAR_HASH_2 TABLESPACE TBS3, ……)<br />
          </pre><h3 class="sub1">함께 쓰일 때 더욱 강력한 리스트 파티셔닝</h3><p>리스트 파티셔닝은 특정 컬럼의 특정 값을 기준으로 파티셔닝을 하는 방식이다. 주로 이질적인(distinct) 값이 많지 않고 분포도가 비슷하며 다양한 SQL의 액세스 패스에서 해당 컬럼의 조건이 많이 들어오는 경우 유용하게 사용된다. 예를 들어 ‘서비스 계약’이라는 테이블이 있고 서비스를 최초 가입한 대리점을 ‘가입 대리점’, 변경사항을 처리한 대리점을 ‘처리 대리점’이라고 한다면 모든 서비스의 가입, 해지, 전환 등의 처리 데이터에는 이 두 대리점이 존재한다. 테이블 구조를 보면 다음과 같다.</p><pre class="sourcebox">          CREATE TABLE SERVICE_CONTRACT<br />
          <br />
           (I_YYYYMMDD VARCHAR2(8), I_CUSTOMER VARCHAR2(6),<br />
          <br />
           I_DLR_IND VARCHAR2(2), I_DEALER VARCHAR2(6), ……)<br />
          </pre><p>즉 I_DLR_IND(대리점 구분)라는 컬럼이 존재하고 ‘A’일 때는 ‘가입 대리점’, ‘S’일 때는 ‘처리 대리점’이라고 할 때 대부분의 조회 패턴에는 가입 대리점 또는 처리 대리점에 해당하는 값이 들어오기 마련이다. 이럴 때 I_DLR_IND로 리스트 파티셔닝을 한다면 어떨까. 즉 집합의 서브 타입을 분류할 때 리스트 파티션은 매우 유용하다. 지금 예로 든 것은 단편적인 것에 불과하지만 리스트 파티셔닝의 위력은 강력하다. 특히 컴포지트 파티션에서 레인지 파티션과 함께 사용하면 전체 데이터베이스의 성능을 크게 향상시킬 수 있다. 다음은 리스트 파티션을 만드는 DDL 스크립트이다.</p><pre class="sourcebox">          CREATE TABLE SERVICE_CONTRACT<br />
          <br />
           (I_YYYYMMDD VARCHAR2(8), I_CUSTOMER VARCHAR2(6),<br />
          <br />
           I_DLR_IND VARCHAR2(2), I_DEALER VARCHAR2(6), …….)<br />
          TABLESPACE TBS1<br />
          STORAGE (INITIAL 2M NEXT 2M PCTINCREASE 0)<br />
          PARTITION BY LIST (I_DLR_IND)<br />
          <br />
           (PARTITION PAR_A VALUES (‘A’), PARTITION PAR_S VALUES (‘S’))<br />
          </pre><p>PARTITION BY LIST에 나타나는 COLUMN_LIST는 파티셔닝 컬럼으로 파티션 키에 해당하고(단 단일 컬럼만 지정할 수 있다), VALUESS LESS THAN에 나타나는 VALUE_LIST는 파티셔닝 컬럼들의 값이다. 여기에 나타낸 값에 해당하는 행들을 저장하겠다는 의미가 된다.</p><p>레인지의 장점을 그대로, 레인지-해시 컴포지트 파티셔닝</p><p>레인지-해시 컴포지트 파티셔닝은 레인지 방식을 사용해 데이터를 파티셔닝하고 각각의 파티션 내에서 해시 방식으로 서브 파티셔닝하는 방식이다. 서브 파티션이 독립된 세그먼트가 되는 것이 특징으로, 다음과 같은 장점이 있다.</p><p class="sourcebox">◆ 관리와 성능 등 레인지 파티션의 장점을 그대로 수용한다.<br />
◆ 해시 파티션의 이점인 데이터 균등 배치와 병렬화<br />
◆ 서브 파티션에 특정 테이블스페이스를 지정할 수 있다.<br />
◆ 서브 파티션별로 풀 스캔을 할 수 있어 스캔 범위를 줄여 성능을 향상시킨다.</p><p>레인지 파티션에서 해당 테이블이 단지 논리적인 구조이고 실제 데이터는 파티셔닝된 세그먼트에 저장됐던 것처럼 컴포지트 파티션에서도 해당 테이블과 파티셔닝된 테이블은 단지 파티셔닝을 위한 논리적인 구조일 뿐이다. 데이터는 가장 하위에 위치한 서브 파티션 영역에 저장된다. 다음은 레인지-해시 컴포지트 파티션을 생성하는 DDL 스크립트이다. PARTITION BY RANGE (I_YYYYMMDD)에 의해 레인지로 파티션을 한 후 SUBPARTITION BY HASH에 의해 서브 파티셔닝을 수행했음을 알 수 있다.</p><pre class="sourcebox">          CREATE TABE TB_RANGE_HASH<br />
          <br />
           (I_YYYYMMDD VARCHAR2(8), I_SERIAL NUMBER, SALE_PRICE NUMBER, ……)<br />
          TABLESPACE TBS1<br />
          STORAGE (INITIAL 2M NEXT 2M PCTINCREASE 0)<br />
          PARTITION BY RANGE (I_YYYYMMDD)<br />
          SUBPARTITION BY HASH (I_SERIAL)<br />
          <br />
           (PARTITION SALES_1997 VALUES LESS THAN (‘19980101’)<br />
          <br />
           (SUBPARTITION SALES_1997_Q1 TABLESPACE TBS2,<br />
          <br />
           SUBPARTITION SALES_1997_Q2 TABLESPACE TBS3), ……)<br />
          </pre><h3 class="sub1">레인지-리스트 컴포지트 파티셔닝</h3><p>레인지-리스트 컴포지트 파티셔닝은 레인지 방식을 사용해 데이터를 파티셔닝하고 각 파티션 안에서 리스트 방식을 이용해 서브 파티셔닝하는 방식이다(이때 서브 파티션은 독립된 세그먼트가 된다). 레인지-리스트 컴포지트 파티션은 레인지-해시 컴포지트 파티션과 비슷하지만 서브 파티션이 리스트 파티션이라는 점이 다르다. 실제 업무에서는 레인지-해시보다 유용한 면이 많다. 다음은 레인지-리스트 컴포지트 파티션을 생성하는 DDL 스크립트이다.</p><pre class="sourcebox">          CREATE TABLE TB_RANGE_LIST (<br />
          <br />
           I_YYYYMMDD VARCHAR2(8), I_AGR_IND VARCHAR2(2), I_DELAER VARCHAR2(6), …….)<br />
          TABLESPACE TBS1<br />
          STORAGE (INITIAL 2M NEXT 2M PCTINCREASE 0 MAXEXTENTS UNLIMITED)<br />
          PARTITION BY RANGE (I_YYYYMMDD)<br />
          SUBPARTITION BY LIST (I_AGR_IND) <br />
          <br />
           (PARTITION PAR_1997 VALUES LESS THAN (‘19980101’)<br />
          <br />
           (SUBPARTITION PAR_1997_A VALUES (‘A’), SUBPARTITION PAR_1997_A VALUES (‘S’)),<br />
          <br />
           ……)<br />
          </pre><h3 class="sub1">파티션된 인덱스의 참뜻</h3><p>‘파티션된 인덱스(partitioned index)’라고 하면 대부분의 개발자들은 로컬 인덱스를 떠올린다. 또한 파티션된 테이블에서만 쓰이는 것으로 생각한다. 그러나 이것은 명백한 오산이다. 파티션된 인덱스는 파티션된 테이블과 별개의 것으로, 단지 많은 상호 연관을 갖고 있을 뿐이다. 파티션된 인덱스는 문자 그대로 인덱스를 파티셔닝한 것으로, 해당 테이블이 파티션된 테이블이든 파티션되지 않은(non-parti tioned) 테이블이든 상관없이 만들 수 있다. 예를 들면 ‘EMP’ 테이블의 크기가 상당히 크고 파티션되지 않은 일반 테이블일 경우 다음과 같은 과정을 통해 파티션된 인덱스를 만들 수 있다. 이를 ‘Global Prefixed Partitioned Index’라고 부르는데, 파티션 인덱스와 마찬가지로 대용량 데이터 환경에서 성능을 높이고 관리를 편리하게 하기 위해서다.</p><p><strong>&lt;그림 1&gt; 파티션된 인덱스와 파티션되지 않은 인덱스의 차이</strong><br />
<img src="http://www.dbguide.net/images/know/clum/050826_db_07.jpg"></p><pre class="sourcebox">          CREATE INDEX EMP_IDX1 ON EMP (DEPTNO)<br />
          GLOBAL<br />
          PARTITION BY RANGE (DEPTNO)<br />
          <br />
           (PARTITION PAR_10 VALUES LESS THAN (‘20’) TABLESPACE TBS1,<br />
          <br />
           PARTITION PAR_20 VALUES LESS THAN (‘30’) TABLESPACE TBS2,<br />
          <br />
           PARTITION PAR_30 VALUES LESS THAN (‘40’) TABLESPACE TBS3,<br />
          <br />
           PARTITION PAR_40 VALUES LESS THAN (‘50’) TABLESPACE TBS4,<br />
          <br />
           PARTITION PAR_MAX VALUES LESS THAN (MAXVALUE) TABLESPACE TBS5)<br />
          </pre><p>파티션된 인덱스가 유용한 이유는, 앞서 파티션의 개념에서 설명한 것처럼 하나의 인덱스를 여러 개의 독립적인 물리 속성을 가진 세그먼트로 나누어 생성, 관리할 수 있기 때문이다. 오라클 DBMS에서 제공하는 인덱스는 글로벌/로컬 인덱스와 Prefixed/Non-Prefixed 인덱스로 분류된다.</p><p>파티션된 인덱스와 일반 인덱스 사이의 차이점은 파티션 테이블과 일반 테이블의 그것과 동일하다. 인덱스는 인덱스 컬럼과 Rowid 순으로 값이 정렬되는데, 이런 특성은 파티션 인덱스에서도 동일하다. 많은 개발자들이 파티션된 인덱스는 전체 테이블 값이 정렬되지 않는다고 생각하지만 이것은 사실과 다르다. 글로벌 파티션된 인덱스의 경우 테이블에 대해 값 정렬이 보장돼 있으며, 인덱스도 파티션별로 독립적으로 관리할 수 있다. 두 가지 방식의 차이는 &lt;그림 1&gt;과 같다.</p><p>파티션되지 않은 인덱스는 하나의 루트(root) 노드에서 리프(leaf) 노드까지 전체적인 밸런스를 유지하는 구조이고, 파티션 인덱스는 파티션 별로 독립적인 루트 노드와 리프 노드를 갖고 있음을 알 수 있다. 따라서 파티션되지 않으면 대용량 테이블에서는 글로벌 인덱스의 깊이(depth)가 매우 깊어질 수 있는 단점이 있다. 반면 파티션된 인덱스는 각 파티션별 깊이가 일반 인덱스의 깊이보다 얕고 인덱스도 파티션별로 할 수 있어 병렬 프로세싱을 이용한 인덱스 관리에 매우 효과적이다.</p><p>그렇다면 글로벌 인덱스와 로컬 인덱스는 어떤 차이가 있는 것일까? 많은 개발자들이 파티션됐는지 여부로 판단하지만 이것은 잘못된 생각이다. 앞서 설명한 것처럼 글로벌 인덱스도 파티셔닝할 수 있으며, 이를 파티션별로 관리할 수 있다. 글로벌 인덱스와 로컬 인덱스의 가장 큰 차이는 ‘정렬’이다. 글로벌 인덱스는 테이블 전체에 대해 인덱스된 컬럼과 Rowid 순으로 정렬되고, 로컬 인덱스는 해당 파티션 내에서만 인덱스된 컬럼과 Rowid 순으로 정렬된다.</p><p>또한 로컬 인덱스는 ‘Local’이라는 말에서 알 수 있듯이 지역적인 인덱스로, 해당 테이블(base table)의 파티션 키로 파티셔닝된 인덱스다. 일반적으로 로컬 인덱스의 구성 컬럼에 반드시 파티션 키가 포함돼야 가능한 것으로 알려져 있지만 로컬 인덱스에는 파티션 키가 포함되어 있지 않아도 사용할 수 있다.</p><p>다음 예제를 보자. PACKAGE_DLR_IDX1 인덱스의 구성 컬럼에 테이블 파티션 키인 I_DLR_IND가 포함되지 않아도 검색조건에 I_ DLR_IND = ‘C’라는 검색 조건이 있기 때문에 해당 파티션의 로컬 인덱스를 이용하는 것을 알 수 있다.</p><pre class="sourcebox">          select<br />
          *from PACKAGE_DLR<br />
          where i_package = ‘AAA’  and i_dlr_ind = ‘C’<br />
          Operation<br />
          Object Name  PStart PStop<br />
          SELECT STATEMENT Hint=CHOOSE<br />
          <br />
           TABLE ACCESS BY LOCAL INDEX ROWIDPACKAGE_DLR 3 3<br />
          <br />
           INDEX RANGE SCAN  PACKAGE_DLR_IDX1 3 3<br />
          </pre><p>글로벌 인덱스는 전역적인 인덱스로, 기본적으로는 파티션되지 않은 인덱스이다. 대부분의 개발자들은 글로벌 인덱스를 파티셔닝해 사용할 생각을 하지 못하는데, 대용량 테이블에서 인덱스 관리의 효율성을 높이고 인덱스 검색 성능을 높이기 위해서는 이를 파티셔닝하는 것이 좋다.</p><p>글로벌 인덱스는 기본 테이블의 파티션 키와 무관하게 파티셔닝하는 것으로 설사 기본 테이블의 파티션 키로 글로벌 인덱스를 파티셔닝했다고 해도 로컬 인덱스처럼 동일파티셔닝(equipartitioning) 된 개념이 아니므로 테이블 DDL시 전체 인덱스를 다시 생성해야 한다.</p><p>그렇다면 글로벌 파티션 인덱스의 인덱스 컬럼 값은 어떻게 전체 테이블에 대해 정렬을 보장하는 것일까. 예를 들어 5000만 건의 파티션되지 않은 EMP 테이블을 부서번호에 따라 파티셔닝했다고 가정하면 다음과 같다.</p><pre class="sourcebox">          CREATE INDEX EMP_IDX1 ON EMP (DEPTNO)<br />
          GLOBAL<br />
          PARTITION BY RANGE (DEPTNO)<br />
          (PARTITION PAR_10 VALUES LESS THAN (‘20’) TABLESPACE TBS1,<br />
          PARTITION PAR_20 VALUES LESS THAN (‘30’) TABLESPACE TBS2,<br />
          PARTITION PAR_30 VALUES LESS THAN (‘40’) TABLESPACE TBS3,<br />
          PARTITION PAR_40 VALUES LESS THAN (‘50’) TABLESPACE TBS4,<br />
          PARTITION PAR_MAX VALUES LESS THAN (‘MAXVALE’) TABLESPACE TBS2,<br />
          </pre><p>&lt;그림 2&gt;는 Global Prefixed Partitioned 인덱스의 구조다. Pre fixed와 Non-Prefixed는 인덱스 파티셔닝 키가 인덱스의 선두 컬럼으로 오는가 그렇지 않은가의 차이가 있다. &lt;그림 2&gt;에서도 ‘Pre fixed’란 인덱스의 파티션 키(DEPTNO)가 인덱스 선두 컬럼(DEPTNO)이 되는 것을 알 수 있다. 글로벌 인덱스의 경우 모든 인덱스 컬럼 값이 정렬돼 있다. 각 인덱스 파티션의 루트 블럭(root block)에 들어가는 값들이 인덱스 파티션에 따라 정렬되기 때문에 자연적으로 리프 블럭(leaf block)에 들어가는 모든 값들도 정렬되는 것이다. 반면 Global Non-Prefixed 인덱스를 파티셔닝하면 레인지 파티셔닝 방식으로만 가능하다. 이것은 정렬 때문인데, 레인지 파티션은 정렬 기능을 이용해 파티셔닝 키 자체를 생성하는데 반해 다른 파티셔닝 방식은 정렬과 상관없이 수행하기 때문이다.</p><p>로컬 인덱스는 Prefixed 인덱스와 Non-Prefixed 인덱스를 모두 지원한다. 로컬 인덱스는 기본적으로 현재 테이블의 파티션 키가 곧 인덱스 파티션 키가 되기 때문에 인덱스 컬럼에 현재 테이블의 파티션 키가 포함되지 않아도 인덱스를 생성할 수 있다. 또한 인덱스 컬럼 값의 정렬이 전체 테이블에 대해 보장된 것도 아니기 때문에 인덱스 파티션 키가 인덱스의 선두 컬럼이 될 필요가 없다. 또한 Non-Parti tioned 인덱스이든 파티션 인덱스든 상관없이 인덱스를 이용하고자 할 때는 무조건 인덱스 파티션 키를 조회해야 하는 글로벌 인덱스와 달리 로컬 인덱스는 조회 검색조건에 파티션 키가 들어올 수도 있고 들어오지 않을 수도 있다.</p><p><strong>&lt;그림 2&gt; Global Prefixed Partitioned 인덱스</strong><br />
<img src="http://www.dbguide.net/images/know/clum/050826_db_08.jpg"></p><p class="sub1">대용량 DB 테이블과 인덱스 전략</p><p>파티션 인덱스 전략은 파티션 테이블과 밀접하게 연관돼 수립해야 하지만 여기서는 파티션 인덱스를 위주로 이야기를 풀어본다. 먼저 인덱스 크기에 대한 논의는 기본적으로 테이블보다는 훨씬 작게 생성, 관리하는 것이 원칙이다. 따라서 중소 용량의 데이터베이스 환경에서는 파티션 인덱스의 유용성을 따질 필요가 없다. 단 중소 용량의 데이터 환경에서도 테이블이 파티셔닝돼 있다면 파티션 인덱스를 고려해야 한다. 또한 파티션되지 않은 인덱스(일반 인덱스) 전략을 기본으로 해 테이블이 파티셔닝된 경우와 인덱스를 파티셔닝했을 때의 장점을 비교해 봐야 한다.</p><p>먼저 테이블 파티션 키가 항상 ‘=’로 들어오는 경우 또는 파티션 범위가 크지 않은 경우에는 로컬 인덱스가 최상이다. 인덱스 컬럼의 순서와 구성은 액세스 패스에 따라 생성하면 되지만 최대한 가볍게 생성하는 것이 좋다. 기본 테이블의 파티션 키는 반드시 포함될 필요가 없으나, 테이블이 레인지 파티션이고 한 파티션 범위 안에서 파티션 키의 분포도가 좋을 경우 이를 포함하는 것을 고려해 볼만하다. 이렇게 하면 각 파티션당 인덱스가 파티션되지 않았을 때보다 가벼워지고 데이터 마이그레이션을 할 때도 테이블 파티션과 인덱스 파티션이 동일하므로 exchange, add, drop, split 등 파티션별 관리도 용이하다.</p><p>또한 빠른 응답 시간을 요구하는 환경에서 대용량 파티션 테이블의 조회 조건에 파티션 키가 들어오지 않을 가능성이 있다면 파티션 글로벌 인덱스를 고려해 볼만하다. 이렇게 하면 파티션되지 않은 글로벌 인덱스와 달리 레인지 파티션 별로 인덱스가 가벼워지는 장점이 있고, 레인지 파티션 별로 인덱스 split와 rebuild 명령을 독립적으로 수행할 수 있다. 컬럼 분포도에 따른 파티셔닝이나 민감한(critical)한 상수 레인지에 대해서는 파티션을 독립적으로 생성해 인덱스 크기를 줄임으로써 인덱스 검색 시간을 줄일 수 있는 이점도 있다.</p><p>exchange는 파티션된 테이블의 특정 파티션과 파티션되지 않은 일반 테이블 간의 구조를 서로 바꾸는 것으로, 대용량의 파티션된 테이블을 관리하는데 상당한 효과가 있다. &lt;그림 2&gt;와 같이 데이터가 없는 새로운 데이터 테이블과 데이터가 들어 있는 파티션 2를 exch ange하면 파티션 2에 해당하는 디렉토리 정보가 새로운 데이터로 바뀌고 새 테이블에 데이터가 들어간다. 이것은 실제 데이터가 이동하는 것이 아니라 데이터를 저장하는 테이블 정보만을 업데이트하는 것이다. 한 가지 주의할 점은 exchange하고자 하는 파티션과 테이블의 구조가 같아야 하고 속성들의 특성도 같아야 한다는 사실이다. exchange의 기본 문법은 다음과 같다.</p><p><strong>&lt;그림 3&gt; 대용량 DB에서 exchange 작업</strong><br />
<img src="http://www.dbguide.net/images/know/clum/050826_db_09.jpg"></p><p><strong>&lt;그림 4&gt; 대용량 DB에서 split 작업</strong><br />
<img src="http://www.dbguide.net/images/know/clum/050826_db_11.jpg"></p><pre class="sourcebox">          Alter table Tb_Partition<br />
          Exchange partition par_200306<br />
          With table Tb_Exchange<br />
          (Without validation Including indexes)<br />
          </pre><p>한편 파티션된 대용량 테이블에 split 함수를 실행하면 많은 시간이 걸린다. 이럴 때 exchange 기능을 이용하면 빠르고 안전하게 작업할 수 있다. &lt;그림 4&gt;에서 보는 것처럼 split를 해야 하는 파티션을 exchange에 의해 빈 공간으로 만든 다음 split을 하고 다시 데이터를 채우기 위해 split하는 것이다. 이렇게 하면 대용량의 데이터라도 매우 빠른 시간 내에 split 작업을 마칠 수 있다. 한편 대부분의 DBA들과 개발자들은 동일한 테이블을 생성할 때 create table ~ as select 구문을 이용한다. 대용량의 데이터일 경우 parallel 옵션을 주고 생성하기도 한다. 만약 1억 건의 테이블을 그대로 생성한다고 할 때 어떤 방법이 효과적일까. 이렇게 파티션된 대용량 테이블을 생성할 때는 exchange, program parallel 방법을 사용하는 것이 바람직하다.</p><p>&lt;그림 5&gt;는 이 과정을 도식화한 것이다. 먼저 생성할 TB_PART_1 테이블의 빈 껍데기를 만든다. 대용량의 파티션된 테이블의 파티션 각각을 create table ~ as select 구문의 parallel 옵션을 이용해 각 테이블로 생성한다. 미리 생성해 놓은 TB_PART_1 테이블의 파티션과 만들어 놓은 테이블들을 exchange하는 것이다. 이 때 파티션별로 200105.sql, 200106.sql, 200107.sql…… 형식으로 만들어 놓고 이 프로그램들을 동시에 실행하면(program parallel) 극적인 효과를 볼 수 있다.</p><p>이번엔 데이터 마이그레이션에 대해 살펴 보자. 원격으로 데이터를 옮겨야 할 때 보통 database link를 이용한다. 네트워크를 통해 데이터를 옮기면 직렬(serial)로 데이터가 이동되므로 속도가 현저하게 떨어지기 때문이다. 따라서 소스 테이블을 파티셔닝하고 해당 파티션을 액세스하는 프로그램을 각각 띄워 병렬 프로세싱을 하면 매우 빠른 속도로 데이터를 옮길 수 있다. 소스 테이블을 파티셔닝할 수 있는 상황이라면 테이블의 분포를 보고 레인지나 리스트 방식으로 파티셔닝할 수 있고, 일정한 분포가 존재하지 않는 테이블이라면 해시 파티셔닝으로 분포도를 고르게 나눈 다음 해당 파티션을 읽는 뷰를 액세스해 데이터를 옮기는 것이 좋다.</p><p>예를 들어 다음은 중대형 정도 크기인 약 2700만 건의 회원 테이블을 옮기는 DDL 스크립트다. 앞서 언급한 대로 database link를 이용해 처리하면 네트워크의 속도가 떨어져 엄청난 시간이 소요된다. 그러나 이것을 일반 테이블을 여러 개로 파티션을 나누어서 파티션과 병렬 처리하면 성능이 크게 향상된다. 작업 순서는 다음과 같다.</p><pre class="sourcebox">          create table t_cust_hash<br />
          storage (initial 5M next 5M pctincrease 0)<br />
          partition by hash(mem_no)<br />
          <br />
           (<br />
          <br />
           partition par_hash_1 TABLESPACE TS_DATA,<br />
          <br />
           partition par_hash_2 TABLESPACE TS_DATA,<br />
          <br />
           partition par_hash_3 TABLESPACE TS_DATA,<br />
          <br />
           partition par_hash_4 TABLESPACE TS_DATA,<br />
          <br />
           partition par_hash_6 TABLESPACE TS_DATA,<br />
          <br />
           partition par_hash_7 TABLESPACE TS_DATA,<br />
          <br />
           partition par_hash_8 TABLESPACE TS_DATA,<br />
          <br />
           partition par_hash_9 TABLESPACE TS_DATA,<br />
          <br />
           partition par_hash_10 TABLESPACE TS_DATA,<br />
          <br />
           )<br />
          nologging<br />
          as<br />
          select /*+ parallel(x 10) */ * from t_cust x<br />
          이제 다음과 같이 소스 테이블 뷰를 생성한 후<br />
          create or replace view t_cust_1<br />
          as select * from t_cust_hash partition (par_hash_1);<br />
          create or replace view t_cust_2<br />
          as select * from t_cust_hash partition (par_hash_2);<br />
          create or replace view t_cust_3<br />
          as select * from t_cust_hash partition (par_hash_3)<br />
          ……<br />
          다음과 같이 프로그램 패러럴(program parallel) 작업을 동시에 실행한다.<br />
          T_cust_1.sql<br />
          create table t_cust_1<br />
          storage (initial 5M next 5M pctincrease 0)<br />
          nologging<br />
          tablespace njh<br />
          as<br />
          select /*+ parallel(x 4) */ * from t_cust_1@remote x;<br />
          T_cust_2.sql<br />
          create table t_cust_2<br />
          storage (initial 5M next 5M pctincrease 0)<br />
          nologging<br />
          tablespace njh<br />
          as<br />
          select /*+ parallel(x 4) */ * from t_cust_2@remote x<br />
          </pre><p>이것은 단적인 예에 지나지 않는다. 활용할 수 있는 사례는 얼마든지 있다. 한편 인덱스는 전체 데이터에 대해 해당 컬럼의 값으로 정렬하기 때문에 대용량 테이블의 경우 create, rebuild 명령을 실행할 때 많은 시간이 필요하다. 이 때 파티션된 인덱스를 만들면 인덱스의 생성과 관리를 더 효과적으로 할 수 있다. 다음은 파티션된 인덱스를 Unusable로 생성한 사례다(로컬/글로벌 파티션된 인덱스).</p><p>먼저 파티션 인덱스를 ‘unusable’ 옵션을 이용해 생성한다. 실제 데이터를 정렬해 만드는 것이 아니라 일종의 껍데기를 만드는 과정이다. 이제 앞서 살펴본 병렬 처리를 이용해 여러 파티션을 동시에 rebuild를 하면 대용량 데이터라도 빠른 시간에 인덱스를 생성할 수 있다.</p><p><strong>&lt;그림 5&gt; 동일 테이블을 만들 때</strong><br />
<img src="http://www.dbguide.net/images/know/clum/050826_db_10.jpg"></p><pre class="sourcebox">          CREATE INDEX EMP_IDX1 ON EMP (DEPTNO)<br />
          GLOBAL<br />
          PARTITION BY RANGE (DEPTNO)<br />
          <br />
           (PARTITION PAR_10 VALUES LESS THAN (‘20’) TABLESPACE TBS1,<br />
          <br />
           PARTITION PAR_20 VALUES LESS THAN (‘30’) TABLESPACE TBS2,<br />
          <br />
           PARTITION PAR_30 VALUES LESS THAN (‘40’) TABLESPACE TBS3,<br />
          <br />
           PARTITION PAR_40 VALUES LESS THAN (‘50’) TABLESPACE TBS4,<br />
          <br />
           PARTITION PAR_MAX VALUES LESS THAN (MAXVALUE) TABLESPACE TBS5)<br />
          UNUSABLE;<br />
          이제 파티션별로 index1.sql, index2.sql 등을 독립적으로 병렬 실행한다.<br />
          ALTER INDEX EMP_IDX1 REBUILD PARTITION PAR_10 PARALLEL 4;<br />
          ---‘ index1.sql<br />
          ALTER INDEX EMP_IDX1 REBUILD PARTITION PAR_20 PARALLEL 4;<br />
          ---‘ index2.sql<br />
          ALTER INDEX EMP_IDX1 REBUILD PARTITION PAR_30 PARALLEL 4;<br />
          ---‘ index3.sql<br />
          ALTER INDEX EMP_IDX1 REBUILD PARTITION PAR_40 PARALLEL 4;<br />
          ---‘ index4.sql<br />
          ALTER INDEX EMP_IDX1 REBUILD PARTITION PAR_MAX PARALLEL 4; ---‘ index5.sql<br />
          </pre><p>지금까지 테이블 파티셔닝에 대해 다뤄봤다. 자동화된 성능관리 툴로 커버할 수 없는 영역을 살펴보고 있으나 가장 중요한 것은 데이터베이스 액세스 개념에 대해 정확하게 이해하는 것이다. 많은 사람들이 파티셔닝을 알고 있지만 정확하게 사용하고 있지 못하는 현실이 안타까울 때가 많다. 그러나 이 점은 역설적으로 파티셔닝의 매력이기도 하다. 노력하는 데이터베이스 관리자 만이 도전해 볼 수 있는 영역이 바로 ‘파티셔닝’ 분야이기 때문이다.</p></div></div><br />
			 ]]> 
		</description>
		<category>Oracle</category>

		<comments>http://altibase.egloos.com/2308312#comments</comments>
		<pubDate>Fri, 27 Mar 2009 07:13:59 GMT</pubDate>
		<dc:creator>오서비네</dc:creator>
	</item>
	<item>
		<title><![CDATA[ [펌] PE(Partition Exchange)를 이용해 대량의 Delete를 대신하기 ]]> </title>
		<link>http://altibase.egloos.com/2308297</link>
		<guid>http://altibase.egloos.com/2308297</guid>
		<description>
			<![CDATA[ 
  From : http://www.egloos.com/egloo/insert.php?eid=e0040769 (욱짜<span style="font-family: Verdana;"><img src="http://forums.oracle.com/forums/images/status/ace_2.gif"></span><span style="font-family: Verdana;">님의 블로그)</span><br />
<br />
<h2><a style="" href="http://ukja.tistory.com/173">PE(Partition Exchange)를 이용해 대량의 Delete를 대신하기</a></h2>          <span class="name"><a href="http://ukja.tistory.com/category/Advanced%20Oracle">Advanced Oracle</a></span> <span class="date">2008/10/31 17:43</span><br />
                     <p><span class="Apple-style-span" style="font-size: 20px; color: rgb(0, 0, 0); line-height: normal; font-family: -webkit-monospace;"><span style="font-size: 11pt;"><span style="font-size: 10pt;"><span style="font-family: Verdana;">대량의 데이터에 대한 Delete 작업이 필요한 경우가 있다. 가령 다음과 같이...<br />
<br />
<span class="Apple-style-span" style="font-weight: bold;">Table t1의 Column c1 값이 1인 경우에 대해 모든 Data를 삭제하고 싶다.</span><br />
<br />
하지만 이 경우 대량의 Undo와 Redo Data로 인해 심각한 성능 문제가 대두된다. 그래서 이런 경우 다음과 같은 방식이 권장되기도 한다.<br />
</span></span></span></span></p><ul style="list-style-type: square;"><li>Table t1의 Copy 본인 Table t2를 만든다.<br />
</li><li>Table t2에 Column c1 값이 1인 경우를 제외하고 Data를 Copy한다.<br />
</li><li>Table t1을 rename(혹은 drop)하고 Table t2를 t1으로 rename한다.<br />
</li><li>Index를 기존과 똑같은 이름으로 생성한다. <br />
</li></ul><p>위의 방법이 가끔 사용되기는 하지만 몇 가지 골치아픈 절차가 따른다. 가령 Index이름을 어떻게 맞추어 줄 것인가, Down Time을 어떻게 최소화시킬 것인가.... <br />
<br />
이 경우에<span class="Apple-style-span" style="font-weight: bold;"> Partition Exchange</span>를 사용하면 좀 더 간편하게 동일한 목적을 달성할 수 있다. <br />
<br />
아래 예제를 보자.<br />
<br />
다음과 같은 Table t1이 있다.</p><div style="border: 1px dotted rgb(204, 204, 204); padding: 10px; background-color: rgb(255, 255, 255);"><span class="Apple-style-span" style="font-size: 20px; color: rgb(0, 0, 0); line-height: normal; font-family: -webkit-monospace;"></span><span class="Apple-style-span" style="font-size: 20px; color: rgb(0, 0, 0); line-height: normal; font-family: -webkit-monospace;"><span style="font-size: 11pt;"><span style="font-size: 10pt;"><span style="font-family: Verdana;"><span style="font-family: 'Courier New';">create table t1(c1 int, c2 int);<br />
<br />
alter table t1 add constraint t1_pk <br />
primary key (c1, c2);<br />
<br />
create index t1_n2 on t1(c2);<br />
<br />
insert into t1 <br />
select mod(level,5)+1, level<br />
from dual<br />
connect by level &lt;= 10000<br />
;<br />
<br />
select c1, count(*)<br />
from t1<br />
group by c1<br />
;<br />
<br />
C1 COUNT(*) <br />
---------- ---------- <br />
1 2000 <br />
2 2000 <br />
4 2000 <br />
5 2000 <br />
3 2000 </span></span></span></span></span></div><div><span class="Apple-style-span" style="font-size: 20px; color: rgb(0, 0, 0); line-height: normal; font-family: -webkit-monospace;"><span style="font-size: 11pt;"><span style="font-size: 10pt;"><span style="font-family: Verdana;"><br />
<br />
</span></span></span></span></div><div><span class="Apple-style-span" style="font-size: 20px; color: rgb(0, 0, 0); line-height: normal; font-family: -webkit-monospace;"><span style="font-size: 11pt;"><span style="font-size: 10pt;"><span style="font-family: Verdana;">우리의 목적은 Column c1의 값이 "1"인 경우의 Data를 모두 삭제하는 것이다. </span></span></span></span></div><div><span class="Apple-style-span" style="font-size: 13px; color: rgb(0, 0, 0); line-height: normal; font-family: -webkit-monospace;"><br />
<br />
</span></div><div><span class="Apple-style-span" style="font-size: 20px; color: rgb(0, 0, 0); line-height: normal; font-family: -webkit-monospace;"><span style="font-size: 11pt;"><span style="font-size: 10pt;"><span style="font-family: Verdana;">이를 위해서 Table t1의 복사본인 Table t2를 만든다. <br />
<br />
단 Partition Exchange를 사용하기 위해 하나의 Partition으로 구성한다. Column c1 값이 1이 배제되도록 Data를 생성한다. 즉 Column c1의 값이 1인 경우가 삭제된 것과 동일하다.<br />
<br />
</span><div style="border: 1px dotted rgb(204, 204, 204); padding: 10px; background-color: rgb(255, 255, 255);"><span style="font-family: Verdana;"><span style="font-family: 'Courier New';">create table t2(c1, c2)<br />
nologging<br />
partition by range(c1) <br />
(<br />
partition p1 values less than(maxvalue)<br />
) <br />
as <br />
select c1, c2 from t1<br />
where c1 in (2, 3, 4, 5)<br />
;<br />
</span></span></div><br />
<br />
</span></span></span></div><div><span class="Apple-style-span" style="font-size: 20px; color: rgb(0, 0, 0); line-height: normal; font-family: -webkit-monospace;"><span style="font-size: 11pt;"><span style="font-size: 10pt;"><span style="font-family: Verdana;"><br />
Partition Exchange를 위해 Index 구성도 통일시켜준다.<br />
</span></span></span></span></div><div><span class="Apple-style-span" style="font-size: 20px; color: rgb(0, 0, 0); line-height: normal; font-family: -webkit-monospace;"><span style="font-size: 11pt;"><span style="font-size: 10pt;"><span style="font-family: Verdana;"><br />
<span style="font-family: 'Courier New';"><div style="border: 1px dotted rgb(204, 204, 204); padding: 10px; background-color: rgb(255, 255, 255);">create unique index t2_n1 on t2(c1, c2) local;<br />
<br />
alter table t2 add constraint t2_pk <br />
primary key (c1, c2) using index;<br />
<br />
create index t2_n2 on t2(c2) local;</div></span><br />
</span><br />
</span></span></span></div><div><span class="Apple-style-span" style="font-size: 13px; color: rgb(0, 0, 0); line-height: normal; font-family: -webkit-monospace;"><span style="font-family: Verdana;"><font size="2">다음과 같이 Table t1과 Partition t2.p1을 Exchange한다.<br />
</font></span></span></div><div><span class="Apple-style-span" style="font-size: 20px; color: rgb(0, 0, 0); line-height: normal; font-family: -webkit-monospace;"><span style="font-size: 11pt;"><span style="font-size: 10pt;"><span style="font-family: Verdana;"><br />
<span style="font-family: 'Courier New';"><div style="border: 1px dotted rgb(204, 204, 204); padding: 10px; background-color: rgb(255, 255, 255);">alter table t2<br />
exchange partition p1<br />
with table t1<br />
including indexes<br />
;</div></span><br />
</span><br />
</span></span></span></div><div><span class="Apple-style-span" style="font-size: 20px; color: rgb(0, 0, 0); line-height: normal; font-family: -webkit-monospace;"><span style="font-size: 11pt;"><span style="font-size: 10pt;"><span style="font-family: Verdana;">Table t1에서 Column c1의 값이 1인 경우는 완전히 삭제되었다.<br />
</span></span></span></span></div><div><span class="Apple-style-span" style="font-size: 20px; color: rgb(0, 0, 0); line-height: normal; font-family: -webkit-monospace;"><span style="font-size: 11pt;"><span style="font-size: 10pt;"><span style="font-family: Verdana;"><br />
<span style="font-family: 'Courier New';"><div style="border: 1px dotted rgb(204, 204, 204); padding: 10px; background-color: rgb(255, 255, 255);">select c1, count(*)<br />
from t1<br />
group by c1<br />
;<br />
<br />
C1 COUNT(*) <br />
---------- ---------- <br />
2 2000 <br />
4 2000 <br />
5 2000 <br />
3 2000 </div></span><br />
<br />
Table t2는 Table t1으로 교체되었으므로 모든 Data를 가지고 있다. </span></span></span></span></div><div><span class="Apple-style-span" style="font-size: 20px; color: rgb(0, 0, 0); line-height: normal; font-family: -webkit-monospace;"><span style="font-size: 11pt;"><span style="font-size: 10pt;"><span style="font-family: Verdana;"><br />
<span style="font-family: 'Courier New';"><div style="border: 1px dotted rgb(204, 204, 204); padding: 10px; background-color: rgb(255, 255, 255);">select c1, count(*)<br />
from t2<br />
group by c1<br />
;<br />
<br />
C1 COUNT(*) <br />
---------- ---------- <br />
1 2000 <br />
2 2000 <br />
4 2000 <br />
5 2000 <br />
3 2000 </div></span><br />
<br />
</span><br />
<br />
</span></span></span></div><div><span class="Apple-style-span" style="font-size: 13px; color: rgb(0, 0, 0); line-height: normal; font-family: -webkit-monospace;"><span style="font-family: Verdana;"><font size="2">Index 또한 이름이 그대로 유지되며 VALID 상태를 유지한다.<br />
<br />
</font></span></span></div><div style="border: 1px dotted rgb(204, 204, 204); padding: 10px; background-color: rgb(255, 255, 255);"><div><span class="Apple-style-span" style="font-size: 13px; color: rgb(0, 0, 0); line-height: normal; font-family: -webkit-monospace;"><span style="font-family: Verdana;"><br />
</span></span></div><div><span class="Apple-style-span" style="font-size: 20px; color: rgb(0, 0, 0); line-height: normal; font-family: -webkit-monospace;"><span style="font-size: 11pt;"><span style="font-size: 10pt;"><span style="font-family: Verdana;"><br />
<span style="font-family: 'Courier New';">select index_name, status<br />
from user_indexes<br />
where table_name = 'T1'<br />
;<br />
<br />
</span></span></span></span><span class="Apple-style-span" style="font-size: 13px;"><span style="font-family: Verdana;"><span style="font-family: 'Courier New';"><font size="2">INDEX_NAME STATUS <br />
-------------------- ------------------------ <br />
T1_PK VALID <br />
T1_N2 VALID </font></span></span></span></span></div></div><div><span class="Apple-style-span" style="font-size: 20px; color: rgb(0, 0, 0); line-height: normal; font-family: -webkit-monospace;"><span class="Apple-style-span" style="font-size: 13px;"><span style="font-family: Verdana;"></span></span></span>&nbsp;</div><div><span class="Apple-style-span" style="font-size: 13px; color: rgb(0, 0, 0); line-height: normal; font-family: -webkit-monospace;"><br />
<br />
</span></div><div><span class="Apple-style-span" style="font-size: 20px; color: rgb(0, 0, 0); line-height: normal; font-family: -webkit-monospace;"><span class="Apple-style-span" style="font-size: 13px;"><span style="font-family: Verdana;"><font size="2"><span class="Apple-style-span" style="font-weight: bold;">Partition Exchange</span>를 사용함으로써 훨씬 간단하게 원하는 바를 달성할 수 있다. </font></span></span></span></div><div><span class="Apple-style-span" style="font-size: 13px; color: rgb(0, 0, 0); line-height: normal; font-family: Verdana;"><br />
<br />
</span></div><div><span class="Apple-style-span" style="font-size: 20px; color: rgb(0, 0, 0); line-height: normal; font-family: -webkit-monospace;"><span class="Apple-style-span" style="font-size: 13px;"><span style="font-family: Verdana;"><font size="2">간단하지만 유용한 기법이라고 하겠다.</font></span></span></span></div><div><span class="Apple-style-span" style="font-size: 20px; color: rgb(0, 0, 0); line-height: normal; font-family: -webkit-monospace;"><span class="Apple-style-span" style="font-size: 13px;"><br />
</span></span></div><span id="callbacknestukjatistorycom173850" style="width: 1px; height: 1px; float: right;"><embed allowscriptaccess="always" id="bootstrapperukjatistorycom173850" src="http://ukja.tistory.com/plugin/CallBack_bootstrapperSrc?nil_profile=tistory&amp;nil_type=copied_post" wmode="transparent" type="application/x-shockwave-flash" enablecontextmenu="false" flashvars="&amp;callbackId=ukjatistorycom173850&amp;host=http://ukja.tistory.com&amp;embedCodeSrc=http%3A%2F%2Fukja.tistory.com%2Fplugin%2FCallBack_bootstrapper%3F%26src%3Dhttp%3A%2F%2Fcfs.tistory.com%2Fblog%2Fplugins%2FCallBack%2Fcallback%26id%3D173%26callbackId%3Dukjatistorycom173850%26destDocId%3Dcallbacknestukjatistorycom173850%26host%3Dhttp%3A%2F%2Fukja.tistory.com%26float%3Dleft" swliveconnect="true" width="1" height="1"></span><fieldset style="margin: 20px 0px; padding: 5px;"><legend><span><strong>크리에이티브 커먼즈 라이선스</strong></span></legend><!--Creative Commons License--><div style="float: left; width: 88px; margin-top: 3px;"><a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.0/kr/" target="_blank"><img alt="Creative Commons License" style="border-width: 0pt;" src="http://i.creativecommons.org/l/by-nc-sa/2.0/kr/88x31.png"></a></div><div style="margin-left: 92px; margin-top: 3px; text-align: justify;">이 저작물은 <a style="" rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.0/kr/" target="_blank">크리에이티브 커먼즈 코리아 저작자표시-비영리-동일조건변경허락 2.0 대한민국 라이선스</a>에 따라 이용하실 수 있습니다.			<!-- Creative Commons License-->			<!-- <rdf:RDF xmlns="http://web.resource.org/cc/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">			<work rdf:about="">			<license rdf:resource="http://creativecommons.org/licenses/by-nc-sa/2.0/kr/" />			</work>			<license rdf:about="http://creativecommons.org/licenses/by-nc-sa/">			<permits rdf:resource="http://web.resource.org/cc/Reproduction"/>			<permits rdf:resource="http://web.resource.org/cc/Distribution"/>			<requires rdf:resource="http://web.resource.org/cc/Notice"/>			<requires rdf:resource="http://web.resource.org/cc/Attribution"/>			<permits rdf:resource="http://web.resource.org/cc/DerivativeWorks"/>			<requires rdf:resource="http://web.resource.org/cc/ShareAlike"/><prohibits rdf:resource="http://web.resource.org/cc/CommercialUse"/></license></rdf:RDF> --></div></fieldset><h4>'<a href="http://ukja.tistory.com/category/Advanced%20Oracle">Advanced Oracle</a>' 카테고리의 다른 글</h4><table><tbody><tr><th><a href="http://ukja.tistory.com/175">Oracle Library Cache를 이해하기 위한 숙제</a>&nbsp;&nbsp;<span>(1)</span></th><td>2008/11/09</td></tr><tr><th><a href="http://ukja.tistory.com/174">[새로쓴 대용량 데이터베이스 솔루션 I]을 보고 깜짝 놀라다.</a>&nbsp;&nbsp;<span>(9)</span></th><td>2008/11/01</td></tr><tr><th><a href="http://ukja.tistory.com/173" class="current">PE(Partition Exchange)를 이용해 대량의 Delete를 대신하기</a>&nbsp;&nbsp;<span>(11)</span></th><td>2008/10/31</td></tr><tr><th><a href="http://ukja.tistory.com/172">FIRST_ROWS vs. FIRST_ROWS_N 그리고 Cost의 개념</a>&nbsp;&nbsp;<span>(10)</span></th><td>2008/10/23</td></tr><tr><th><a href="http://ukja.tistory.com/171">11g is better  - 10046 Trace가 좋아졌다!!!</a>&nbsp;&nbsp;<span>(0)</span></th></tr></tbody></table><br />
<br />
=======<br />
<ol><li>                                                  </li><li> <span><a style="" href="http://scidb.tistory.com/" onclick="return openLinkInNewWindow(this)">extremedb</a></span> <span>2008/11/02 17:50</span> <span><a href="http://ukja.tistory.com/173#" onclick="deleteComment(1209319);return false">Modify/Delete</a> <a href="http://ukja.tistory.com/173#" onclick="commentComment(1209319); return false">Reply</a></span>                          <p>아주 유용한 예제입니다.<br />
PE 를 이런용도로도 사용하는 군요.^^<br />
대용량 테이블일 경우 down time 을 더 낮추려면   Without Validation 을 적용하는것을 <br />
추가적으로 고려해야 성능이 더욱 좋아질 것입니다.<br />
물론 PE 될 테이블의 데이터가 이미 VALID 된 상태라고 가정하고 말입니다.<br />
좋은글 감사합니다.</p>                                                  </li><li> <span>Stargazer</span> <span>2008/11/03 09:46</span> <span><a href="http://ukja.tistory.com/173#" onclick="deleteComment(1210875);return false">Modify/Delete</a> <a href="http://ukja.tistory.com/173#" onclick="commentComment(1210875); return false">Reply</a></span>                          <p>생각의 전환...역시...대단하십니다..</p>                                                  </li><li> <span>백면서생</span> <span>2008/11/03 16:27</span> <span><a href="http://ukja.tistory.com/173#" onclick="deleteComment(1211905);return false">Modify/Delete</a> <a href="http://ukja.tistory.com/173#" onclick="commentComment(1211905); return false">Reply</a></span>                          <p>좋은 글 잘 봤습니다.~</p>                                                  </li><li> <span>oracler</span> <span>2008/11/08 08:58</span> <span><a href="http://ukja.tistory.com/173#" onclick="deleteComment(1235367);return false">Modify/Delete</a> <a href="http://ukja.tistory.com/173#" onclick="commentComment(1235367); return false">Reply</a></span>                          <p>오...이런,, 좋으네요 그냥 대단하시다는 말밖에 안나옵니다.<br />
<br />
그런데 전통적인 위의 방법에서 인덱스 이름 맟추기와 다운타임 최소화가<br />
왜 문제가 되는지 모르겠네요 ?<br />
결국 alter index rename 과 drop, rename 시간인데 <br />
인덱스 이름 맟추는것도 문제가 없으며 모두 금방 끝나는거 아닌가여</p>                                                  </li><li> <span><a href="http://ukja.tistory.com/" onclick="return openLinkInNewWindow(this)">욱짜</a></span> <span>2008/11/08 11:35</span> <span><a href="http://ukja.tistory.com/173#" onclick="deleteComment(1235523);return false">Modify/Delete</a> <a href="http://ukja.tistory.com/173#" onclick="commentComment(1235523); return false">Reply</a></span>                          <p>인덱스 이름의 경우 전통적인 방법에 비해서 좀 더 편하다 정도로 이해하시면 될 거 같습니다. 수동으로 인덱스 이름을 맞추어주는 경우 오타 등으로 인해 생각지 못한 문제가 발생하는 경우가 종종 있습니다. <br />
<br />
Down Time의 경우에는 DML을 Blocking하는 DDL Operation의 회수가 여러번에서 1번으로 줄어든다 정도의 의미로 이해하시면 될 거 같습니다. 이로 인해 시간이 크게 절약된다는 의미는 아니구요.</p></li></ol><br />
			 ]]> 
		</description>
		<category>Oracle</category>

		<comments>http://altibase.egloos.com/2308297#comments</comments>
		<pubDate>Fri, 27 Mar 2009 06:46:43 GMT</pubDate>
		<dc:creator>오서비네</dc:creator>
	</item>
	<item>
		<title><![CDATA[ [펌] 파티션 관리 ]]> </title>
		<link>http://altibase.egloos.com/2308289</link>
		<guid>http://altibase.egloos.com/2308289</guid>
		<description>
			<![CDATA[ 
  From : http://abcpost.net/598<br />
<br />
																					<!-- 검색 리스트 -->																<!-- 검색 댓글 리스트 -->																		<!-- 위치로그 -->														<!-- 태그 -->															<!-- 방명록 -->					 						<!-- 공지사항 -->														<!-- 보호글 -->											<!-- 본문글 -->																					<!-- 글 제목, 카테고리, 글쓴 날짜 -->						<div class="titleinfo">							<h2><a style="" href="http://abcpost.net/598">파티션 관리</a> <a href="http://abcpost.net/category/Rdbms">Rdbms</a> 2009/03/16 09:18</h2>							 																				</div><br />
<p>파티션은 파티션 테이블 전체가 하나의 오브젝트로 등록되어 관리되며 개별 파티션도 역시 하나의 오브젝트로 관리됨으로 일반 &nbsp;테이블과 인덱스와는 약간 다른 처리가 발생 하게 된다.</p><p>파티션 테이블의 일반적인 백업과 복구에서는 파티션 특성을 제외하면 일반 테이블의 백업과 복구와 특별한 차이가 없다.</p><p>하지만 파티션 인덱스에서는 로컬인덱스와 글로벌 인덱스에 따라서 다른 처리가 발생하게 되며 관리상의 부하도 클 수 있으므로 주의해야 한다.</p><p>파티션의 관리는 크게 다음과 같이 나눌 수 있다.</p><ul><li>파티션 추가/삭제/병합 </li><li>파티션 변환(파티션 테이블과 일반테이블의 변환) </li><li>기타 관리 </li></ul><p>파티션의 종류에 따라 가능한 작업이 정해져 있으며 이는 종류에 따른 파티션의 특성에 기인한다. 파티션의 종류별로 가능한 ALTER 명령은 오라클 매뉴얼을 참고하기 바란다.</p><p>(<a class="con_link" href="http://otn.oracle.com/docs/products/oracle9i/doc_library/901_doc/server.901/a90117/partiti.htm#1311" target="_blank"><u><font color="#0000ff">http://otn.oracle.com/docs/products/oracle9i/<br />
doc_library/901_doc/server.901/a90117/partiti.htm#1311</font></u></a>)</p><p>파티션의 관리는 실제적인 방법과 명령의 사례가 필요하므로 테스트를 위해서 오라클 9i에서 추가된 데모 데이터베이스 Sales History를 예로 든다.</p><p><b>테스트 환경 설정</b></p><p>오라클 9i에 접속 가능한 경우에는 sh 유저의 데이터 베이스에서 확인이 가능한다. 없는 경우를 위해서 간단히 다음과 같이 작업한다.</p><p>테스트를 위해서 먼저 partition table을 다음과 같이 생성한다. 테스트를 위해서 파티션의 데이터 타입을 DD-MON-YYYY 에서 YYYYMMDD로 하였다.</p><pre><font color="maroon">CREATE TABLE sales<br />
    (prod_id       NUMBER(6)    CONSTRAINT sales_product_nn  NOT NULL,<br />
     cust_id       NUMBER       CONSTRAINT sales_customer_nn NOT NULL,<br />
     time_id       DATE         CONSTRAINT sales_time_nn     NOT NULL,<br />
     channel_id    CHAR(1)      CONSTRAINT sales_channel_nn  NOT NULL,<br />
     promo_id      NUMBER(6)   ,<br />
     quantity_sold NUMBER(3)    CONSTRAINT sales_quantity_nn NOT NULL,<br />
     amount        NUMBER(10,2) CONSTRAINT sales_amount_nn   NOT NULL,<br />
     cost          NUMBER(10,2) CONSTRAINT sales_cost_nn     NOT NULL)<br />
   PARTITION BY RANGE (time_id)<br />
   (PARTITION Q1_1998 VALUES LESS THAN (TO_DATE(''''19980401'''',''''YYYYMMDD'''')),<br />
    PARTITION Q2_1998 VALUES LESS THAN (TO_DATE(''''19980701'''',''''YYYYMMDD'''')),<br />
    PARTITION Q3_1998 VALUES LESS THAN (TO_DATE(''''19981001'''',''''YYYYMMDD'''')),<br />
    PARTITION Q4_1998 VALUES LESS THAN (TO_DATE(''''19990101'''',''''YYYYMMDD'''')),<br />
    PARTITION Q1_1999 VALUES LESS THAN (TO_DATE(''''19990401'''',''''YYYYMMDD'''')),<br />
    PARTITION Q2_1999 VALUES LESS THAN (TO_DATE(''''19990701'''',''''YYYYMMDD'''')),<br />
    PARTITION Q3_1999 VALUES LESS THAN (TO_DATE(''''19991001'''',''''YYYYMMDD'''')),<br />
    PARTITION Q4_1999 VALUES LESS THAN (TO_DATE(''''20000101'''',''''YYYYMMDD'''')),<br />
    PARTITION Q1_2000 VALUES LESS THAN (TO_DATE(''''20000401'''',''''YYYYMMDD'''')),<br />
    PARTITION Q2_2000 VALUES LESS THAN (TO_DATE(''''20000701'''',''''YYYYMMDD'''')),<br />
    PARTITION Q3_2000 VALUES LESS THAN (TO_DATE(''''20001001'''',''''YYYYMMDD'''')),<br />
    PARTITION Q4_9999 VALUES LESS THAN (MAXVALUE));<br />
<br />
INSERT INTO SALES<br />
SELECT PROD_ID, CUST_ID,<br />
       ADD_MONTHS(TIME_ID,(ROWNUM-1)*3)+1 TIME_ID,<br />
       CHANNEL_ID, PROMO_ID, QUANTITY_SOLD, AMOUNT_SOLD, ROWNUM<br />
 FROM SH.SALES<br />
 WHERE ROWNUM &lt;= 20 ;<br />
<br />
COMMIT ;<br />
</font><br />
<br />
 </pre><p>위 테이블은 time_id를 partition key로 한 range partition table이다. 다음엔 이sales table에 SQL*Loader를 이용하여 데이터를 loading한다. 해당 control 화일 및 데이터 화일은다음 디렉토리에 있다. 이 디렉토리로 이동해서 작업을 하면 된다.</p><p><font color="maroon">$ORACLE_HOME/demo/schema/sales_history</font></p><p>Note :</p><p>Oracle 9i부터는 $ORACLE_HOME/demo/schema 서브 디렉토리에 HR(human resource),OE(order entry), PM(product media), SH(sales history), QS(QueuedShipping) 등의 샘플 스키마 및 데이터들이 있다.</p><p>가장 일반적인 RANGE PARTITION을 기준으로 설명하며 COMPOSITE PARTITION의 경우 서브파티션만HASH로 추가된 경우이므로 RANGE PARTITITON 과 같다고 보면 되며 HASH와 LIST 파티션의 경우에는 따로설명하였다.</p><p><b>1. 파티션의 추가/삭제/분할/병합</b></p><p><b>1.1. 추가</b></p><p>기존에 존재하는 파티션에 새로운 파티션을 추가하려는 경우 (예:리스트 파티션에서 2001년 1분기 데이터를 추가하려는 경우등) 예제처럼 MAXVALUE로 지정한 파티션처럼 기존 파티션안에 대상이 포함되어 있다면 아래의 분할(SPLIT)을 이용하여처리하고 MAXVALUE가 없는 경우처럼 기존 파티션의 범위 밖으로 새로이 추가되는 경우라면 다음과 같이 한다.</p><p><font color="maroon">SQL&gt;alter table sales add partition Q1_2001<br />
values less than (''''20010101'''') tablespace pts_2001Q1 ;</font></p><p>MAXVALUE로 지정한 파티션이 있는데 위와 같이 추가(add)하면 다음과 같은 에러가 발생한다. </p><p><font color="maroon">"ORA-14120:DATE열에 파티션 바운드가 불완전하게 지정되었습니다."</font></p><p><b>1.2. 삭제</b></p><p>해당 단위 파티션을 삭제하는 경우 1998년 1분기 및 이전 데이터를 더 이상 관리하지 않아 해당 파티션 Q1_1998을 없애고 싶은 경우는 다음과 같이 실행한다.</p><p><font color="maroon">SQL&gt;alter table sales drop partition Q1_1998 ;</font></p><p>해당 파티션 및 파티션 안의 모든 데이터가 같이 삭제 된다. drop된 후에 새로 1998년 1분기 및 이전 데이타가입력되면 Q2_1998 partition이 less then (''''19980701'''') 으로 되어 있으므로 Q2_1998partition에 저장된다.</p><p><b>1.3. 분할</b></p><p>하나의 파티션을 분할하여 여러 개의 파티션으로 재 생성시 MAXVALUE를 이용한 경우에 경계값으로 새로 추가되는 경우,MAXVALUE로 바운드를 지정하지 않은경우 새로운 최대값을 지정하는, 기존 하나의 파티션을 둘 이상의 파티션으로 나누는 경우등이 해당된다.</p><p>새로 추가될 데이터 2001년 1분기 데이터를 저장할 파티션을 추가하려는 경우 기존 MAXVALUE 파티션에 이 조건이 포함되어 있으므로 이 파티션을 분할하면 된다.</p><p><font color="maroon">SQL&gt;alter table sales split partition Q4_9999 at (TO_DATE(''''20010101'''',''''YYYYMMDD''''))<br />
into (partition Q4_2000 tablespace pts_2000Q4, partition Q4_9999 tablespace pts_9999Q4)</font></p><p>분할되는 기존 파티션을 그대로 사용할 경우에는 기존 파티션 정보를 그대로 기술해 주면 된다.</p><p>SPLIT PARTITION은 매우 큰 partition table이나 view를 handling 하는데 유용하다.</p><p><b>1.4. 병합 </b></p><p>파티션을 병합하는 방법은 MERGE명령을 이용하는 방법과 SQL로 임시테이블에 옮기는 방법과 Export/Import를 이용하는 방법이 있다.</p><p>MERGE를 이용하는 방법이 빠르고 단순하게 처리 가능한다.</p><ul><li>MERGE를 이용하는 방법 </li></ul><p><font color="maroon">SQL&gt; ALTER TABLE SALES MERGE PARTITIONS Q2_1999, Q3_1999 INTO PARTITION Q3_1999 ;</font></p><p><b>1.5. 이름 변경</b></p><p>partition name 을 바꾸고 싶다면 다음과 같이 실행한다.</p><p><font color="maroon">SQL&gt;alter table sales rename partition Q4_9999 to Q4_Max ;</font></p><p><b>1.6. 테이블 스페이스 이동</b></p><p>partition Q4_9999을 저장하는 tablespace를 pts_9999Q4 에서 pts_maxQ4로 바꾸고 싶은 경우아래와 같은 command를 사용한다.</p><p><font color="maroon">SQL&gt;alter table sales move partition Q4_9999 tablespace pts_maxQ4 nologging ;</font></p><p><b>1.7. Truncate</b></p><p>partition의 data를 모두 삭제하려면 truncate하는 방법을 사용할 수 있는 데, truncate는 rollback 이 불가능하며 특정 partition 전체를 삭제하므로 주의하여 사용해야 한다.</p><p><font color="maroon">SQL&gt;alter table sales truncate partition Q4_9999 ;</font></p><p><b>1.8. 속성 변경</b></p><p>partition table은 특정 partition의 속성만 변경할 수도 있고, table의 속성을 변경 하여 전체 partition에 대해 동일한 변경을 할 수 있다.</p><p><font color="maroon">SQL&gt;alter table sales storage(next 10M);</font></p><p>sales 의 모든 partition의 next 값이 변경된다.</p><p><font color="maroon">SQL&gt;alter table part_tbl modify partition Q4_9999 storage(maxextents 100);</font></p><p>Q4_9999 partition의 maxextents 값만 변경한다.</p><p><b>1.9. 인덱스 관리</b></p><p>파티션은 파티션별로 RowID를 다르게 갖게 됨으로 파티션의 변경이 발생하게 되면 RowID의 변경이 발생하게 된다.</p><p>그래서 실제 파티션 테이블의 RowID와 변경된 파티션 로컬 인덱스와 글로벌 인덱스의 &nbsp;RowID와 가 일치하지 않게 되어인덱스 사용 중지 즉, IU상태(INDEX UNUSABLE)가 발생하게 되어 인덱스의 사용 불가 및 재 성성에 따른 운영 및관리상의 부하 및 재 생성에 따른 시스템의 부하가 발생하게 된다.</p><p>partition index가 IU 상태가 되었을때 그 partition index을 사용 하게 되면 다음과 같은 에러가 발생하게 된다.</p><p><font color="maroon">SQL&gt;SELECT /*+ INDEX(SALES SALES_GPNK1) */ *<br />
FROM SALES WHERE PROD_ID &gt;= 10000</font></p><p>ORA-01502: 인덱스 ''''SALES_GPNK1''''또는 인덱스 분할영역은 사용할 수없는 상태이다</p><p>이와 같은 에러가 발생시 해당 파티션을 해당 인덱스를 통해서 엑세스 할 수 없게 됨으로 해당 어플리케이션의 수행을 유지 할 수 없는 상황이 발생하게 된다.</p><p>물론 인덱스를 사용하지 않고 해당 파티션을 TABLE FULL SCAN 하면 에러가 발생 하지 않는다.</p><p>하지만 옵티마이져가 실행계획 수립시에 INDEX UNUSABLE 상태 여부를 체크하지 않으므로 해당 인덱스를 사용하는실행계획이 수립되고 실제 수행시 오류가 발생하게 됨으로 이미 운용중인 어플리케이션이나 SQL이 정상 수행되지 않는다.</p><p>이런 경우에는 <font color="maroon">skip_unusable_indexes = TRUE</font> 파라메터를 지정하면 수행시에 해당 인덱스가 UNUSABLE이면 이를 사용하지 않고 TABLE FULL SCAN 등을 한다. 경우에 따라서 유용하게 사용 가능하므로 고려 해 볼 수 있다. </p><p>어떤 partition이 IU 상태가 되면 그 partition을 사용하기 전에 재생성(rebuild)해야 한다. 그러나IU partition을 제외한 다른 partition만을 읽거나 DML을 수행하는 작업은 IU partition을access하지 않는 한 오류가 발생하지 않는다. 단, IU partition을 rebuild하기 전에 split이나rename이 가능하며, IU상태인 global index를 drop하는 것도 가능하다. 관리상으로 IU상태인 인덱스를 다시수행 가능하게 하는 작업은 경우에 따라 업무적인 부하가 큰 경우가 발생 할 수 있다.</p><p>파티션은 원래 대용량 데이터에 대한 처리이므로 인덱스 재생성 작업은 부하가 큰 작업인 경우가 많다. 또한 로컬파티션인덱스의 경우에는 해당 로컬인덱스만 재 생성해주면 되지만 글로벌 파티션 인덱스의 경우 글로벌 인덱스를 한번에 재 생성할 수 없고개별 파티션 단위로만 재생성이 가능하므로 글로벌 인덱스의 파티션 수 만큼 나누어서 지정하여 재생성 해야 한다.</p><p>이와 같은 관리상의 문제점을 해결하기 위한 여러가지 방법이 있으며 가장 큰 원인은 파티션의 변경과 파티션 데이터의 RowID가 변경되는 경우이다.</p><p>RowID가 변경되는 경우는 자주 발생하지 않고 어쩔수 없는 경우가 대부분일 것이므로 그렇다고 하여도 파티션의 변경은 가능한 발생하지 않게 유도할 수 있다.</p><p>특정 파티션의 데이터를 파티션에서 제외시키는(백업으로 이동 등) 경우에는 실제 데이터를 로우 단위로 Delete 하는것이아니라면 파티션에 대한 명령에서는 실제 데이터의 RowID 변경이 일어난다면 어떤 방법을 써도 Global Index의Unusable을 피할 수는 없다. </p><p><font color="maroon">Partition Index를 Unusable상태로 만들 수 있는 명령.(Oracle9i 기준).</font></p><table width="100%" border="1" cellpadding="2" cellspacing="0"><tbody><tr><td><p><b>작업 대상</b></p></td><td><p><b>작업유형</b></p></td><td><p><b>인덱스</b></p></td><td><p><b>Unusable 상태 변경</b></p></td></tr><tr><td rowspan="16"><p>파티션 테이블</p></td><td rowspan="2"><p>ADD</p></td><td><p>LOCAL</p></td><td><p>새로 생성되므로 상관없다.</p></td></tr><tr><td><p>GLOBAL</p></td><td><p>파티션만 추가되므로 상관없다.</p></td></tr><tr><td rowspan="2"><p>DROP</p></td><td><p>LOCAL</p></td><td><p>같이 삭제되므로 상관없다.</p></td></tr><tr><td><p>GLOBAL</p></td><td><p><font color="maroon">모든 GLOBAL INDEX가 Unusable</font></p></td></tr><tr><td rowspan="2"><p>SPLIT</p></td><td><p>LOCAL</p></td><td><p><font color="maroon">SPLIT된 파티션 인덱스 Unusable</font></p></td></tr><tr><td><p>GLOBAL</p></td><td><p><font color="maroon">모든 GLOBAL INDEX가 Unusable</font></p></td></tr><tr><td rowspan="2"><p>MERGE</p></td><td><p>LOCAL</p></td><td><p><font color="maroon">머지되어 남는 파티션 인덱스 Unusable</font> </p></td></tr><tr><td><p>GLOBAL</p></td><td><p><font color="maroon">모든 GLOBAL INDEX가 Unusable</font></p></td></tr><tr><td rowspan="2"><p>RENAME</p></td><td><p>LOCAL</p></td><td><p>실제 변경이 없으므로 상관없다.</p></td></tr><tr><td><p>GLOBAL</p></td><td><p>실제 변경이 없으므로 상관없다.</p></td></tr><tr><td rowspan="2"><p>MOVE</p></td><td><p>LOCAL</p></td><td><p><font color="maroon">MOVE된 파티션 인덱스 Unusable</font></p></td></tr><tr><td><p>GLOBAL</p></td><td><p><font color="maroon">모든 GLOBAL INDEX가 Unusable</font></p></td></tr><tr><td rowspan="2"><p>TRUNCATE</p></td><td><p>LOCAL</p></td><td><p>남은 로우가 없으므로 상관없다.</p></td></tr><tr><td><p>GLOBAL</p></td><td><p><font color="maroon">모든 GLOBAL INDEX가 Unusable</font></p></td></tr><tr><td rowspan="2"><p>EXCHANGE</p></td><td><p>LOCAL</p></td><td><p><font color="maroon">EXCHANGE한 파티션 인덱스 Unusable</font></p></td></tr><tr><td><p>GLOBAL</p></td><td><p><font color="maroon">모든 GLOBAL INDEX가 Unusable</font></p></td></tr></tbody></table><p>(표를 보면 알겠지만 Unusable상태가 되는 것은 실제 파티션 테이블 데이터의 RowID를 변경시킨 경우(파티션 단위의 변경이 발생시에도 해당 파티션에 실제 로우 데이터가 있어서 RowID 변경이 발생된 경우)에 해당된다.)</p><ul><li>&nbsp;인덱스 재생성(Rebuild) </li></ul><p>partition table관련 작업을 한 후에는 table에 걸려 있는 local(partitioned) index 나 global index를 반드시 rebuild해 주어야 한다.</p><p>특정 partition의 index를 rebuild 하려면</p><p><font color="maroon">SQL&gt;alter index idx01_sales rebuild partition idx_Q4_9999 ;</font></p><p>global index를 rebuild하려면 non-partition index 인덱스인 경우는</p><p><font color="maroon">SQL&gt;alter index sales_idx01 rebuild;</font></p><p>와 같이 처리하면 되지만 global partition index 인덱스는 인덱스 전체를 한번에 재생성 할 수 없다.</p><p><font color="maroon">SQL&gt;alter index SALES_GPNK1 rebuild</font></p><p>"ORA-14086:분할영역된 인덱스는 전체를 다시 만들 수 없습니다." 와 같은 에러를 발생하게 된다.</p><p><font color="maroon">SQL&gt;alter index SALES_GPNK1 rebuild partition SALES_GPI01 ;</font></p><p>위와 같이 인덱스 파티션 단위로 재 생성 해주어야만 한다.</p><p>global partition index의 경우 non-partition index 이든<span id="callbacknestabcpostnet5988365" style="width: 1px; height: 1px; float: right;"><embed allowscriptaccess="always" id="bootstrapperabcpostnet5988365" src="http://abcpost.net/plugin/CallBack_bootstrapperSrc?nil_profile=tistory&amp;nil_type=copied_post" wmode="transparent" type="application/x-shockwave-flash" enablecontextmenu="false" flashvars="&amp;callbackId=abcpostnet5988365&amp;host=http://abcpost.net&amp;embedCodeSrc=http%3A%2F%2Fabcpost.net%2Fplugin%2FCallBack_bootstrapper%3F%26src%3Dhttp%3A%2F%2Fcfs.tistory.com%2Fblog%2Fplugins%2FCallBack%2Fcallback%26id%3D598%26callbackId%3Dabcpostnet5988365%26destDocId%3Dcallbacknestabcpostnet5988365%26host%3Dhttp%3A%2F%2Fabcpost.net%26float%3Dleft" swliveconnect="true" width="1" height="1"></span>partition index 이든 파티션 테이블 관련 작업인 경우 재 생성이 필수 이므로 파티션 테이블별로 globalindex의 rebuild 작업용의 스크립트를 작성해 놓아야 빠른 시간안에 관련 인덱스를 재 생성 할 수 있다.</p><p><b>1.10. Index Unusable 상태 예방</b></p><p>특히 Range Partition의 경우 대개 날짜를 키로 하여 파티션되며 시간의 경과에 따라 관리하는 데이터의 날짜값도 증가하여 새로운 파티션으로 관리해야 하는 경우가 많다.</p><p>오라클에서 NULL 데이터는 정렬에서 마지막에 위치하게 되어 파티션 키의 값이 NULL인 경우 MAXVALUE 파티션에 존재하게 된다.</p><p>즉 키에 NULL인 데이터가 존재시에는 MAXVALUE에 실제로 데이터가 위치하게 되며 이 경우 최신의 데이터를 위해서파티션을 추가시 MAXVALUE를 SPLIT하게 되면 실제 데이터 로우가 있는 파티션에서 변경 작업이 일어났으므로 GlobalIndex 의 Unusable를 피할 수 없게 된다.</p><p>이를 방지 하기 위해서는 실제 운영데이터의 최종 파티션과 MAXVALUE 파티션 사이에 dummy 파티션을 하나 두어 NULL값이 위치한 MAXVALUE 파티션을 분리하는 것이 좋다. </p><p>예를 들어 날짜가 키인 경우 ''''20021001''''인 현재 파티션과 MAXVALUE 사이에''''21000101'''' 이나 ''''99990101'''' 과 같은 dummy 파티션을 유지 하여 실무에서 유용하게사용하는 방법이다.</p><p><b>1.11. 파티션 키 데이터의 변경</b></p><p>파티션을 운영 중에 키 컬럼의 데이터가 변경되어 파티션을 이동 시에 다음과 같은 에러를 발생시킨다.</p><p>"ORA-14402: 분할영역 키 열을 수정하는 것은 분할영역 변경이 생깁니다."</p><p>이 문제를 해결하기 위해 잘못하면 &nbsp;프로그램 상에서 Delete &amp; Insert 방식으로 코딩을 하기도 하지만 Oracle8i부터 SQL의 Syntax에 이 문제에 대한 옵션이 존재한다.</p><p><font color="maroon">ENABLE ROW MOVEMENT 또는 DISABLE ROW MOVEMENT</font></p><p>디폴트로 DISABLE ROW MOVEMENT 가 셋팅 되어 있다. 즉 파티션간 로우의 이동이 금지되어 있었기 때문에 위와 같은 에러를 만나게 된 것이다.</p><p>CREATE TABLE시 이 옵션을 주거나, ALTER TABLE 명령어로 설정 값을 바꿀 수 있다.</p><p><font color="maroon">ALTER TABLE SALES ENABLE ROW MOVEMENT;</font></p><p><b>2. 파티션 테이블의 변환 (파티션과 일반테이블의 변환)</b></p><p>파티션 테이블과 일반 테이블을 직접 변환시키는 명령은 EXCHANGE 명령이 있으며 다른 데이터베이스에의 이전이라면 Export/Import를 이용하는 방법이 있다.</p><p>EXCHANGE 명령은 특정 partition을 non partitioned table로, non partitioned table을 특정 partition으로 변환시켜 주는 역할을 한다.</p><p>내부적으로는 data(index) segment를 교환(data dictionary의 변경)하는 것이지 실제로 각각의 row들을 옮기는 것은 아니다.</p><p>Export/Import를 이하는 방법은 다른 데이터 베이스에서의 이전 등이나 재생성 등에 유용하며 일반 테이블의 Import와 동일한 절차로 수행된다.</p><p>table-level import시 우선 table creation 문장을 수행하고 row insert문을 수행 하는 것과마찬가지로, partition-level import도 우선 partitioned table의 생성문장을 수행하고 rowinsert문을 수행하게 된다.</p><p>따라서 ignore=y option등을 적절히 사용하면, non-partitioned table과 partitioned table간의 변경, partitioned table의 구조 변경 등을 수행할 수 있게 된다.</p><p><b>2.1. EXCHANGE 이용 시</b></p><ul><li>파티션 =&gt; 일반 테이블의 변환 </li></ul><p>table을 변환하기 위해 dummy table을 생성하고, alter table EXCHANGE PARTITION 명령어를 통해 수행한다. 이 명령어는 매우 빨리 data dictionary 를 update 시킨다</p><p>i) 변경하려는 파티션과 동일한 구조를 같는 테이블을 생성한다.</p><p><font color="maroon">SQL&gt;create table sales_EXCH as select * from sales where 1 = 2 ;</font></p><p>ii) alter table EXCHANGE을 이용하여 변경한다.</p><p><font color="maroon">SQL&gt;ALTER TABLE sales EXCHANGE PARTITION Q4_9999 WITH TABLE<br />
sales_EXCH WITHOUT VALIDATION ;</font></p><p>EXCHANGE 으로 변경시에 파티션 테이블의 해당 파티션의 구조는 그대로 유지된다.(기존 파티션은 데이터 로우는 없는 빈파티션이 된다) 즉 EXCHANGE를 사용하면 실제 데이터가 파티션에서는 더 이상 유지되지 못하므로 해당 경우에만 사용할 수있는 단점이 있다.</p><p>WITHOUT VALIDATION 을 사용하면 유일성 조건 등의 기존 테이블에 걸린 제약 조건을 체크하지 않으므로 변환 전에 미리 체크 하는 것이 좋다.</p><ul><li>일반 테이블 =&gt; 파티션 의 변환 </li></ul><p>alter table EXCHANGE을 이용하여 변경한다.</p><p><font color="maroon">SQL&gt;ALTER TABLE sales EXCHANGE PARTITION Q3_1999 WITH TABLE<br />
sales_EXCH WITHOUT VALIDATION ;</font></p><p>변환될 파티션테이블의 인덱스와 완전히 매치되는 인덱스 구조를 가지고 있다면 INCLUDING INDEX 옵션을 추가하여 로컬인덱스 생성에 대한 시간을 줄일 수 있다.</p><p>EXCHANGE는 전체적으로 가장 빠르게 파티션 관련 데이터를 변경할 수 있는 방법이다.</p><p><b>2.2. CTAS 이용 시</b></p><p>파티션 테이블의 특정 테이블을 일반 테이블로 변경시에 EXCHANGE를 사용시에는 실 데이터의 변경이 발생하므로 또 다른 방법으로 CTAS(CREATE TABLE .. NOLOGGING AS SELECT ..)가 있다.</p><p>적당한 SORT_AREA_SIZE의 지정과 NOLOGGING옵션으로 원하는 성능을 얻을 수 있다.</p><p><b>3. 기타 관리</b></p><p>파티션의 관리에서 발생하게 되는 몇 가지 중요한 실례를 살펴보기로 한다.</p><p><b>3.1. 파티션 데이터 파일 삭제시의 처리</b></p><p>Partitioned table의 partition이 포함되어 있는 datafile이 OS level에서 삭제된 경우,해당 datafile을 offline drop하고 open한 후 해당 table을 access하고자 하는 경우, 또는 해당TableSpace를 Drop하고자 하면 에러가 발생한다. 다음과 같은 error가 유발된다.</p><p><font color="maroon">ORA-00376: (File cannot be read at this time) ,<br />
ORA-14404: (Partitioned table contains partitions in a different tablespace)</font></p><p>파일 삭제에 대한 처리는 일반 데이터 파일 삭제의 처리와 같다.</p><p>이때 파티션의 복구에 대해서는 다음과 같이 3가지로 조치 가능 한다.</p><p>1) 해당 partitioned table전체를 drop한 후 recreate한다.</p><ul><li>drop table sales ; </li><li>drop tablespace pts_9999Q4 including contents ; </li><li>tablespace recreate. </li><li>table rebuild . </li></ul><p>문제점은 전체 partitioned table을 복구해야 하므로 시간이 오래 &nbsp;소요된다.</p><p>2) 해당 partition만을 drop후 재 생성 한다.</p><ul><li>alter table sales drop partition Q4_9999 ; </li><li>drop tablespace pts_9999Q4 including contents ; </li><li>tablespace recreate. </li><li>add partition or split partition. </li><li>해당 partition만의 data를 reload한다. </li></ul><p>partitioned table전체 data를 reload하는 것 보다 짧은 시간이 소요된다.</p><p>3) temporary table을 생성하여 exchange한다.</p><ul><li>sales table과 동일한 구조의 dummy table을 다른 tablespace에 생성한다. <ul><li><font color="maroon">create table dummy_sales as select * from sales where 1=2;</font> </li></ul></li><li>이 table을 문제의 partition과 exchange한다. <ul><li><font color="maroon">alter table sales exchange partition Q4_9999 with table dummy_sales without validation ;</font> </li></ul></li><li>drop tablespace pts_9999Q4 including contents ; </li><li>새로운 partition에 필요한 data를 load한다. </li></ul><p><b>3.2. INDEX UNUSABLE 상태 예방 (9iR1 기준)</b></p><p>Oracle 9i에서는 base table에 대한 DDL 수행 시 UPDATE GLOBAL INDEXES라는 option을 사용해서 global index에 대해서도 ONLINE으로 update할 수 있는 기능을 제공한다.</p><p>이 기능으로 Global index가 base table과 동시에 변경이 되어 Global index에 대한 rebuild를 관리하지 않아도 된다.</p><ul><li>가능한 DDL 명령 </li></ul><p>: SPLIT, MERGE, ADD, MOVE, COALESCE, DROP, TRUNCATE, EXCHANGE UPDATEGLOBAL INDEXES라는 option을 partition specification 바로 뒤, 그리고 PARALLELclause 바로 앞에 기술해 두면 ONLINE으로 base table에 대한 DDL을 수행 하면서 global index를그에 맞춰 변경시킬 수 있다.</p><p><font color="maroon">SQL&gt;ALTER TABLE sales DROP PARTITION sales1 UPDATE GLOBAL INDEXES<br />
PARALLEL (DEGREE 4);</font></p><p>OnLine 변경은 전체적인 처리의 부하가 Rebuild보다 크며 트랜젝션에 대한 처리 시간이 증가 하므로 이 방법은 처리해야 할 row의 양이 적을 때 유용하다.</p><p>변경하려는 데이터에 대한 처리와 재생성의 부하를 비교하여 적정한 방법을 선택하는 것이 좋다. (즉 전체 글로벌 인덱스를 재생성하는 시간보다 ONLINE update 하는 시간이 적을 때 유리하며 다량의 데이터의 경우에는 오히려 전체 시간이 더 걸릴수 도 있으므로 테스트하여 운영 시스템마다 적정선의 처리 한계를 정하는 것이 좋다.)</p><p><b>3.3. 파티션 추가시 로컬인덱스의 속성 관리</b></p><p>ALTER TABLE ADD PARTITION을 할 경우 table partition의 경우 table partition,tablespace, physical storage attribute를 지정할 수 있으나, local indexpartition의 경우 관련 syntax를 지원하지 않는다.</p><p>오라클은 자동으로 index partition, tablespace, physical storage attribute를 지정한다. (ALTER TABLE SPLIT PARTITION도 마찬가지)</p><p>new index partition의 이름은 new table partition과 같은 이름이 할당되고,tablespace, physical storage attribute는 local index에 지정된 default값이사용되고, local index에 지정된 default값이 없으면 user의 default tablespace가 사용된다.그러므로 PARTITION을 추가하여 사용하는 경우 index partition 관리에 주의가 요구된다.</p><p>지금까지 파티션 테이블 및 인덱스의 관리에서 발생할 수 있는 문제점들을 살펴보았다.</p><p>실무에서 파티션의 INDEX UNUSABLE 상태를 일으킬 수 있는 상황들에 대해서 특히 주의 깊게 보고 운영 버전별로 테스트 해보아 각 시스템에 맞는 관리 지침을 수립 하여 숙지 하는 것이 중요하다.</p><p>이상으로 Partition table 및 인덱스의 관리에 대한 일반적인 사례 중심으로 알아보았으며 다음 연재에서는 Partition table 활용 및 제한 사항에 대하여 다루게 될 것이다.</p><h4>'<a href="http://abcpost.net/category/Rdbms">Rdbms</a>' 카테고리의 다른 글</h4><table><tbody><tr><th><a href="http://abcpost.net/28">오라클 테이블 스페이스 이동(데이터 파일 이동)</a>&nbsp;&nbsp;<span>(0)</span></th><td>2009/03/16</td></tr><tr><th><a href="http://abcpost.net/27">오라클 함수(ORACLE FUNCTION)</a>&nbsp;&nbsp;<span>(0)</span></th><td>2009/03/16</td></tr><tr><th><a href="http://abcpost.net/26">8i 오라클 종료시 반응이 없을때 처리 방법</a>&nbsp;&nbsp;<span>(0)</span></th><td>2009/03/16</td></tr><tr><th><a href="http://abcpost.net/598" class="current">파티션 관리</a>&nbsp;&nbsp;<span>(0)</span></th><td>2009/03/16</td></tr><tr><th><a href="http://abcpost.net/1755">테이블스페이스 현황</a>&nbsp;&nbsp;<span>(0)</span></th><td>2009/03/16</td></tr><tr><th><a href="http://abcpost.net/1754">오라클 락(Lock) 정보</a>&nbsp;&nbsp;<span>(0)</span></th><td>2009/03/16</td></tr><tr><th><a href="http://abcpost.net/1753">특정 세션이 접근하고 있는 OBJECT</a>&nbsp;&nbsp;<span>(0)</span></th><td>2009/03/16</td></tr><tr><th><a href="http://abcpost.net/1752">Dictionary 조회 SQL</a>&nbsp;&nbsp;<span>(0)</span></th><td>2009/03/16</td></tr></tbody></table><br />
			 ]]> 
		</description>
		<category>Oracle</category>

		<comments>http://altibase.egloos.com/2308289#comments</comments>
		<pubDate>Fri, 27 Mar 2009 06:34:51 GMT</pubDate>
		<dc:creator>오서비네</dc:creator>
	</item>
	<item>
		<title><![CDATA[ [펌] sqlldr 성능 옵션 ]]> </title>
		<link>http://altibase.egloos.com/2293601</link>
		<guid>http://altibase.egloos.com/2293601</guid>
		<description>
			<![CDATA[ 
  From : http://www.oracleclub.com/articlelist.action<br />
<br />
<table width="650" border="0" cellpadding="0" cellspacing="0"><tbody><tr class="tableOut" onmouseover="this.className='tableOver'" onmouseout="this.className='tableOut'" align="center" height="22"><td class="grayS" width="30">73</td>        <td style="padding: 2px 10px 0pt 15px;" align="left">                                    <a href="javascript:goViewForm('11879');" class="tableA">Oracle SQL*Loader Case Study X</a>                                </td>        <td width="80">안병훈</td>        <td class="txtS" width="100">2006-06-11</td>        <td class="txtS" width="40">2116</td>        <td class="txtS" width="40">8</td>    </tr>    <tr><td class="tableL" colspan="6" width="650" height="1"><br />
</td></tr>    <tr class="tableOut" onmouseover="this.className='tableOver'" onmouseout="this.className='tableOut'" align="center" height="22">        <td class="grayS" width="30">72</td>        <td style="padding: 2px 10px 0pt 15px;" align="left">                                    <a href="javascript:goViewForm('11878');" class="tableA">Oracle SQL*Loader Case Study VIV</a>                                </td>        <td width="80">안병훈</td>        <td class="txtS" width="100">2006-06-11</td>        <td class="txtS" width="40">787</td>        <td class="txtS" width="40">7</td>    </tr>    <tr><td class="tableL" colspan="6" width="650" height="1"><br />
</td></tr>    <tr class="tableOut" onmouseover="this.className='tableOver'" onmouseout="this.className='tableOut'" align="center" height="22">        <td class="grayS" width="30">71</td>        <td style="padding: 2px 10px 0pt 15px;" align="left">                                    <a href="javascript:goViewForm('11877');" class="tableA">Oracle SQL*Loader Case Study VIII</a>                                </td>        <td width="80">안병훈</td>        <td class="txtS" width="100">2006-06-11</td>        <td class="txtS" width="40">730</td>        <td class="txtS" width="40">8</td>    </tr>    <tr><td class="tableL" colspan="6" width="650" height="1"><br />
</td></tr>    <tr class="tableOut" onmouseover="this.className='tableOver'" onmouseout="this.className='tableOut'" align="center" height="22">        <td class="grayS" width="30">70</td>        <td style="padding: 2px 10px 0pt 15px;" align="left">                                    <a href="javascript:goViewForm('11876');" class="tableA">Oracle SQL*Loader Case Study VII</a>                                </td>        <td width="80">안병훈</td>        <td class="txtS" width="100">2006-06-10</td>        <td class="txtS" width="40">832</td>        <td class="txtS" width="40">8</td>    </tr>    <tr><td class="tableL" colspan="6" width="650" height="1"><br />
</td></tr>    <tr class="tableOver" onmouseover="this.className='tableOver'" onmouseout="this.className='tableOut'" align="center" height="22">        <td class="grayS" width="30">69</td>        <td style="padding: 2px 10px 0pt 15px;" align="left">                                    <a href="javascript:goViewForm('11875');" class="tableA">Oracle SQL*Loader Case Study VI</a>                                </td>        <td width="80">안병훈</td>        <td class="txtS" width="100">2006-06-10</td>        <td class="txtS" width="40">742</td>        <td class="txtS" width="40">7</td></tr></tbody></table><table width="650" border="0" cellpadding="0" cellspacing="0"><tbody><tr class="tableOut" onmouseover="this.className='tableOver'" onmouseout="this.className='tableOut'" align="center" height="22"><td class="grayS" width="30">68</td>        <td style="padding: 2px 10px 0pt 15px;" align="left">                                    <a href="javascript:goViewForm('11874');" class="tableA">Oracle SQL*Loader Case Study V</a>                                </td>        <td width="80">안병훈</td>        <td class="txtS" width="100">2006-06-10</td>        <td class="txtS" width="40">703</td>        <td class="txtS" width="40">7</td>    </tr>    <tr><td class="tableL" colspan="6" width="650" height="1"><br />
</td></tr>    <tr class="tableOut" onmouseover="this.className='tableOver'" onmouseout="this.className='tableOut'" align="center" height="22">        <td class="grayS" width="30">67</td>        <td style="padding: 2px 10px 0pt 15px;" align="left">                                    <a href="javascript:goViewForm('11870');" class="tableA">Oracle SQL*Loader Case Study IV</a>                                </td>        <td width="80">안병훈</td>        <td class="txtS" width="100">2006-06-10</td>        <td class="txtS" width="40">822</td>        <td class="txtS" width="40">8</td>    </tr>    <tr><td class="tableL" colspan="6" width="650" height="1"><br />
</td></tr>    <tr class="tableOut" onmouseover="this.className='tableOver'" onmouseout="this.className='tableOut'" align="center" height="22">        <td class="grayS" width="30">66</td>        <td style="padding: 2px 10px 0pt 15px;" align="left">                                    <a href="javascript:goViewForm('11869');" class="tableA">Oracle SQL*Loader Case Study III</a>                                </td>        <td width="80">안병훈</td>        <td class="txtS" width="100">2006-06-10</td>        <td class="txtS" width="40">1141</td>        <td class="txtS" width="40">9</td>    </tr>    <tr><td class="tableL" colspan="6" width="650" height="1"><br />
</td></tr>    <tr class="tableOut" onmouseover="this.className='tableOver'" onmouseout="this.className='tableOut'" align="center" height="22">        <td class="grayS" width="30">65</td>        <td style="padding: 2px 10px 0pt 15px;" align="left">                                    <a href="javascript:goViewForm('11868');" class="tableA">Oracle SQL*Loader Case Study II</a>                                </td>        <td width="80">안병훈</td>        <td class="txtS" width="100">2006-06-10</td>        <td class="txtS" width="40">972</td>        <td class="txtS" width="40">7</td>    </tr>    <tr><td class="tableL" colspan="6" width="650" height="1"><br />
</td></tr>    <tr class="tableOut" onmouseover="this.className='tableOver'" onmouseout="this.className='tableOut'" align="center" height="22">        <td class="grayS" width="30">64</td>        <td style="padding: 2px 10px 0pt 15px;" align="left">                                    <a href="javascript:goViewForm('11867');" class="tableA">Oracle SQL*Loader Case Study I</a>                                </td>        <td width="80">안병훈</td>        <td class="txtS" width="100">2006-06-10</td>        <td class="txtS" width="40">2220</td>        <td class="txtS" width="40">9</td>    </tr>    <tr><td class="tableL" colspan="6" width="650" height="1"><br />
</td></tr>    <tr class="tableOut" onmouseover="this.className='tableOver'" onmouseout="this.className='tableOut'" align="center" height="22">        <td class="grayS" width="30">63</td>        <td style="padding: 2px 10px 0pt 15px;" align="left">                                    <a href="javascript:goViewForm('11861');" class="tableA">SQL*Loader [참고용]</a>                        <span class="idxS">[1]</span>        </td>        <td width="80">안병훈</td>        <td class="txtS" width="100">2006-06-09</td>        <td class="txtS" width="40">1362</td>        <td class="txtS" width="40">8</td></tr></tbody></table>			 ]]> 
		</description>
		<category>Oracle</category>

		<comments>http://altibase.egloos.com/2293601#comments</comments>
		<pubDate>Mon, 09 Mar 2009 14:57:22 GMT</pubDate>
		<dc:creator>오서비네</dc:creator>
	</item>
	<item>
		<title><![CDATA[ [펌]SQL*LOADER 의 성능 향상 TIP ]]> </title>
		<link>http://altibase.egloos.com/2293590</link>
		<guid>http://altibase.egloos.com/2293590</guid>
		<description>
			<![CDATA[ 
  <br />
<br />
<table width="100%" border="0" cellpadding="0" cellspacing="0"><tbody><tr valign="top"><td width="75%" height="25"><span class="bold">[펌]SQL*LOADER 의 성능 향상 TIP</span><img src="http://www.dbguide.net/blog_main/img/blog/gab_01.gif" width="16" height="11"><span class="light">기본게시판</span></td>                            <td class="ver" width="25%" align="right" height="25">2008-11-11 22:32</td>                          </tr>                          <tr>                             <td colspan="2" background="/blog_main/img/blog/dot2.gif" height="1"><br />
</td>                          </tr>                          <tr>                             <td colspan="2" class="ver9_light" valign="middle" align="right" height="25"><a href="http://www.dbguide.net/blog/post/post_view.jsp?urlid=jinhyeon&amp;cnum=28100&amp;pnum=13081"><span class="ver9_light">http://blog.dbguide.net/jinhyeon/13081</span></a></td>                          </tr>                          <tr>                             <td colspan="2" height="20"><br />
</td>                          </tr>                          <tr>                             <td colspan="2">                            <!-- 내용 -->                            	<table style="table-layout: fixed;" width="100%" border="0" cellpadding="0" cellspacing="0">                            		                            		<tbody><tr>                            				                            		<td>                            <img src="http://www.dbguide.net/blog/images/blank.gif" width="1" border="0" height="10"><br />
	                            		<p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><font size="2"><font face="바탕"><strong><span lang="EN-US">10g 에서 SQL*LOADER </span>의 성능 향상</strong><span lang="EN-US"><strong> TIP</strong>&nbsp;&nbsp;&nbsp; </span></font></font></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><font size="2"><font face="바탕"><span lang="EN-US"></span></font></font>&nbsp;</p><p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><font size="2"><font face="바탕"><span lang="EN-US">작성:김도근</span></font></font></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><font size="2"><font face="바탕"><span lang="EN-US"></span></font></font>&nbsp;</p><p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><font size="2"><font face="바탕"><span lang="EN-US"></span></font></font>&nbsp;</p><p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><font size="2"><font face="바탕"><span lang="EN-US">SQL*LOADER 사용시에 여러가지 적절한 옵션 사용과 테이블에 대한 설정값들을 변경시켜줍으로써 많은 성능 향상을 가져올수 있다.</span></font></font></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><font size="2"><font face="바탕"><span lang="EN-US">다음은 그 권장되는 설정법들을 설명한 것이다. </span></font></font></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span lang="EN-US"><o:p><font size="2" face="바탕">&nbsp;</font></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><font size="2"><font face="바탕"><span lang="EN-US">1. DIRECT PATH LOAD</span>를 사용한다<span lang="EN-US">. Direct path load</span>는<span lang="EN-US"> load</span>되는 테이블이나 파티션에<span lang="EN-US"> exclusive access</span>를 요구한다<span lang="EN-US">. </span>추가적으로 트리거는 자동으로<span lang="EN-US"> disable</span>되고 제약조건은 로드가 완료될때까지<span lang="EN-US"> defer(</span>연기<span lang="EN-US">) </span>된다<span lang="EN-US">.</span></font></font></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><font size="2"><font face="바탕"><span lang="EN-US"></span></font></font>&nbsp;</p><p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span lang="EN-US"><o:p><font size="2" face="바탕">&nbsp;</font></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><font size="2"><font face="바탕"><span lang="EN-US">2. direct path load</span>로 데이타를 로드시에 모든 <b><span lang="EN-US">CHECK</span></b><span lang="EN-US"> </span>와 <b><span lang="EN-US">REFERENCE</span></b><span lang="EN-US"> </span>무결성 제약조건은 자동으로<span lang="EN-US"> DISABLE</span>된다<span lang="EN-US">. </span>그러나 그밖의 다른 타입의 제약조건<span lang="EN-US"> NOT NULL, UNIQUE, PRIMARY KEY </span>조건들은 반드시<span lang="EN-US"> DISABLE </span>시켜준다<span lang="EN-US">. </span>작업 완료후에 수동으로<span lang="EN-US"> enable</span>시켜준다<span lang="EN-US">. </span></font></font></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span lang="EN-US"><o:p><font size="2" face="바탕">&nbsp;</font></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span lang="EN-US"><o:p></o:p></span>&nbsp;</p><p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><font size="2"><font face="바탕"><span lang="EN-US">3. </span>정렬된 순서로 데이타를<span lang="EN-US"> load</span>한다<span lang="EN-US">. </span>미리<span lang="EN-US"> sorting </span>된 데이타는 정렬에 필요한 공간<span lang="EN-US">temporary </span>영역 사용을 최소화한다<span lang="EN-US">. SQL*LOADER </span>옵션에서 <b><span lang="EN-US">SORTED INDEXES</span></b><span lang="EN-US"> </span>를<span lang="EN-US"> CONTROL</span>파일에 기술한다<span lang="EN-US">.</span></font></font></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span lang="EN-US"><o:p><font size="2" face="바탕">&nbsp;</font></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span lang="EN-US"><o:p></o:p></span>&nbsp;</p><p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><font size="2"><font face="바탕"><span lang="EN-US">4. </span>인덱스<span lang="EN-US"> MAINTANCE </span>를 연기<span lang="EN-US">(DEFERRING)</span>하라<span lang="EN-US">. </span>인덱스는 데이타가<span lang="EN-US"> insert</span>하거나<span lang="EN-US"> delete </span>또는<span lang="EN-US"> key </span>컬럼이 업데이트 될때마다 자동으로<span lang="EN-US"> maintance </span>를 실시한다<span lang="EN-US">.</span>따라서 많은 양의 데이타를<span lang="EN-US"> load</span>할때 작업이 종료된 후에<span lang="EN-US"> maintance</span>를 한다면 좀더 빠를 것이다<span lang="EN-US">. <b>SKIP_INDEX_MAINTENANCE = TRUE</b><span style="">&nbsp; </span></span>를 설정하면 인덱스 세그먼트의 상태가 </font><span style="font-family: '',Times New Roman,'';" lang="EN-US">“</span><span lang="EN-US"><font face="바탕"> INDEX UNUSABLE</font></span><span style="font-family: '',Times New Roman,'';" lang="EN-US">”</span><font face="바탕">상태가 되어있더라도<span lang="EN-US"> LOADER</span>시작시에 인덱스<span lang="EN-US"> MAINTANCE</span>를<span lang="EN-US"> SKIP</span>한다<span lang="EN-US">. </span></font></font></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span lang="EN-US"><o:p><font size="2" face="바탕">&nbsp;</font></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span lang="EN-US"><o:p></o:p></span>&nbsp;</p><p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><font size="2"><font face="바탕"><span lang="EN-US">5. <b>UNRECOVERABLE</b> </span>을 사용해서<span lang="EN-US"> REDO </span>생성을<span lang="EN-US"> DISABLE</span>시킨다<span lang="EN-US">. </span>모든<span lang="EN-US"> recover </span>시에는<span lang="EN-US"> redo log</span>파일이 필요하다<span lang="EN-US">. </span>그러나<span lang="EN-US"> redo log </span>생성은 부하가 많기 때문에<span lang="EN-US"> disable</span>시키면 그만큼 속도는 빠르게 된다<span lang="EN-US">. </span>그러나<span lang="EN-US"> LOADER </span>작업 중간에<span lang="EN-US"> FAILURE </span>가 발생한다면 처음부터<span lang="EN-US"> load</span>작업을 다시 해야한다<span lang="EN-US">. </span>따라서 리두로그를 생성하지 않기때문에<span lang="EN-US"> loader </span>작업 후에는 반드시 백업하도록 한다<span lang="EN-US">.</span></font></font></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><font size="2"><font face="바탕"><span lang="EN-US"></span></font></font>&nbsp;</p><p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span lang="EN-US"><o:p><font size="2" face="바탕">&nbsp;</font></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><font size="2"><font face="바탕"><span lang="EN-US">6. </span><b>단일 파티션</b>에<span lang="EN-US"> loading </span>하도록 한다<span lang="EN-US">. </span>파티션 테이블에 데이타<span lang="EN-US"> load</span>시 기타 사용자는 다른 파티션 에 접근 할 수 있다<span lang="EN-US">. APRIL </span>파티션을 로드시에<span lang="EN-US"> jan </span>에서<span lang="EN-US"> april </span>까지 쿼리를 실행하는 유저를 차단하지 못한다<span lang="EN-US">. </span>따라서 부하가 증가한다<span lang="EN-US">. </span></font></font></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span lang="EN-US"><o:p><font size="2" face="바탕">&nbsp;</font></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span lang="EN-US"><o:p></o:p></span>&nbsp;</p><p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><font size="2"><font face="바탕"><span lang="EN-US">7. <b>Parallel</b> </span>로 로드를 한다<span lang="EN-US">. </span>파티션으로 구성되어 있다면<span lang="EN-US"> parallel </span>로 다중 파티션을 로드할 수 있다<span lang="EN-US">. </span></font></font></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span lang="EN-US"><o:p><font size="2" face="바탕">&nbsp;</font></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span lang="EN-US"><o:p></o:p></span>&nbsp;</p><p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><font size="2"><font face="바탕"><span lang="EN-US">8. <strong>STREAMSIZE</strong> </span>파라미터는<span lang="EN-US"> SQL*LOADER client </span>에서<span lang="EN-US"> oracle server</span>로 <span style="color: black;" lang="EN">direct path stream buffer</span><span lang="EN"> </span>의 크기<span lang="EN-US">(bytes)</span>를 지정한다<span lang="EN-US">. </span>기본값은<span lang="EN-US"> 256000 bytes </span>이다<span lang="EN-US">.<span style="">&nbsp; </span></span>또한<span lang="EN-US"> </span></font></font></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><font size="2"><font face="바탕"><span style="color: black;" lang="EN">columnarrayrows </span><span style="color: black;">또한 <span lang="EN">direct path column array </span>에 전송하는<span lang="EN"> row</span>의 갯수를 지정한다<span lang="EN">.<o:p></o:p></span></span></font></font></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span style="color: black;"><font size="2"><font face="바탕">기본값은<span lang="EN"> 5000</span>이다<span lang="EN">.<o:p></o:p></span></font></font></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span style="color: black;" lang="EN"><o:p><font size="2" face="바탕">&nbsp;</font></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span style="color: black;" lang="EN"><o:p></o:p></span>&nbsp;</p><p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><font size="2"><font face="바탕"><span style="color: black;" lang="EN">9. </span><span style="color: black;">만일<span lang="EN"> load</span>되는 데이타가 중복되는 날자값을 많이 가지고 있다면 <b><span lang="EN">DATE_CACHE</span></b><span lang="EN"> </span>파라미터를 설정해서<span lang="EN"> DIRECT PATH LOAD</span>시에 더 나은 성능을 보장할 수 있다<span lang="EN">.<o:p></o:p></span></span></font></font></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><font size="2"><font face="바탕"><span style="color: black;" lang="EN">CACHE</span><span style="color: black;">에<span lang="EN"> CONVERION </span>되는<span lang="EN"> DATE </span>의 사이즈<span lang="EN">(</span>엔트리<span lang="EN">)</span>를 지정한다<span lang="EN">. (</span>기본값은<span lang="EN"> 1000) </span></span></font></font><span style="" lang="EN"><o:p></o:p></span></p><p>출처명: 	                            		</p></td></tr></tbody></table></td></tr></tbody></table><br />
			 ]]> 
		</description>
		<category>Oracle</category>

		<comments>http://altibase.egloos.com/2293590#comments</comments>
		<pubDate>Mon, 09 Mar 2009 14:50:10 GMT</pubDate>
		<dc:creator>오서비네</dc:creator>
	</item>
	<item>
		<title><![CDATA[ OS file cache  ]]> </title>
		<link>http://altibase.egloos.com/2288724</link>
		<guid>http://altibase.egloos.com/2288724</guid>
		<description>
			<![CDATA[ 
  <br />
<br />
From : http://data.altibase.com/pdf/a3/htm/admin/apbs01.h<br />
FILE Cache 사용량 확인.<br />
<br />
From : http://www.sunmanagers.org/archives/2000/2018.html<br />
<br />
SUN<br />
*****<br />
If you are running Solaris 7 (or higher I think) and your data filesystems<br />
are UFS, then you can mount them using the option 'noatime' (that will<br />
prevent updating the access time info on each inode, reducing overall disk<br />
usage) and 'forcedirectio' (will disable the Solaris filesystem cache for<br />
this filesystem). See the mount_ufs man page.<br />
<br />
<span style="font-weight: bold;">HP</span><br />
From : http://docs.hp.com/ko/5991-6472/ch06s16.html<br />
<br />
<h1>Unified File Cache</h1><!--stopindex--><!-- End Page Title Area --><!-- Begin Left Navigation and Content Area.  To increase width of content area, modify width of table below. --><table width="740" border="0" cellpadding="0" cellspacing="0"><tbody><tr><!-- Start Left Navigation --><td valign="top" width="170" align="left" bgcolor="#f0f0f0"><table width="170" background="/img/s.gif" border="0" cellpadding="0" cellspacing="0"><tbody><tr class="colorDCDCDCbg"><td width="10" align="left"><img src="http://docs.hp.com/img/s.gif" alt="" width="10" height="1"></td><td class="color003366bld" valign="top" width="10" align="left">»&nbsp;</td><td valign="middle" align="left"><h2><a href="http://docs.hp.com/ko/index.html" class="linkLineBold">      기술 문서    </a></h2></td></tr></tbody></table><table width="170" background="/img/s.gif" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td valign="top" width="10" align="left"><img src="http://docs.hp.com/img/s.gif" alt="" width="10" height="1"></td><td valign="top" width="150" align="left"><table width="150" background="/img/s.gif" border="0" cellpadding="0" cellspacing="0"><tbody><tr class="decoration"><td width="10" align="left"><img src="http://docs.hp.com/img/s.gif" alt="" height="10"></td><td width="10" align="left"><img src="http://docs.hp.com/img/s.gif" alt="" height="10"></td><td width="10" align="left"><img src="http://docs.hp.com/img/s.gif" alt="" height="10"></td><td width="120" align="left"><img src="http://docs.hp.com/img/s.gif" alt="" height="10"></td></tr><tr><td class="color003366" valign="top" width="20" align="left"><img src="http://docs.hp.com/img/pdf_icon.png"></td><td colspan="3" valign="top" align="left"><a href="http://docs.hp.com/ko/5991-6472/5991-6472.pdf" class="linkLine">PDF 완본</a></td></tr><tr class="decoration"><td colspan="4" width="150" align="left"><img src="http://docs.hp.com/img/s.gif" alt="" width="150" height="10"></td></tr></tbody></table><table width="150" background="/img/s.gif" border="0" cellpadding="0" cellspacing="0"><tbody><tr class="decoration"><td width="10" align="left"><img src="http://docs.hp.com/img/s.gif" alt="" width="10" height="1"></td><td valign="top" width="123" align="left" bgcolor="#cccccc"><img src="http://docs.hp.com/img/s.gif" alt="" width="123" height="1"></td><td width="17" align="left"><img src="http://docs.hp.com/img/s.gif" alt="" width="17" height="1"></td></tr></tbody></table><table width="150" background="/img/s.gif" border="0" cellpadding="0" cellspacing="0"><tbody><tr class="decoration"><td width="10" align="left"><img src="http://docs.hp.com/img/s.gif" alt="" height="10"></td><td width="10" align="left"><img src="http://docs.hp.com/img/s.gif" alt="" height="10"></td><td width="10" align="left"><img src="http://docs.hp.com/img/s.gif" alt="" height="10"></td><td width="120" align="left"><img src="http://docs.hp.com/img/s.gif" alt="" height="10"></td></tr><tr><td class="color003366" valign="top" width="10" align="left">»</td><td colspan="3" valign="top" align="left"><a href="http://docs.hp.com/ko/feedback.html" class="linkLine">        피드백      </a></td></tr><tr class="decoration"><td colspan="4" width="150" align="left"><img src="http://docs.hp.com/img/s.gif" alt="" width="150" height="10"></td></tr></tbody></table></td><td valign="top" width="10" align="left"><img src="http://docs.hp.com/img/s.gif" alt="" width="10" height="1"></td></tr><tr class="decoration"><td colspan="3" class="colorCCCCCCbg"><img src="http://docs.hp.com/img/s.gif" alt="" width="1" border="0" height="2"></td></tr></tbody></table></td><!-- End Left Navigation --><!-- Begin Gutter Cell 10px Wide --><td width="10"><a id="jumptocontent" name="jumptocontent"><img src="http://docs.hp.com/img/s.gif" alt="내용 시작 위치" width="10" height="1"></a></td><!-- End Gutter Cell 10px Wide --><!--startindex--><!-- Start Content Area.  To increase width of content area, modify width of table cell below. --><td valign="top" width="560" align="left"><table width="560" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="color666666bg" align="center"><h2 class="colorFFFFFFbld" title="목차">&nbsp;»&nbsp;<a href="http://docs.hp.com/ko/5991-6472/index.html" class="colorFFFFFFbld">목차</a></h2></td><td class="color666666bg" valign="top" width="5"><img src="http://docs.hp.com/img/hpweb_1-2_tab_right.gif" alt="" width="5" border="0" height="23"></td><td width="2"><img src="http://docs.hp.com/img/s.gif" alt="" class="decoration" width="2" height="1"></td></tr></tbody></table><div class="navheader"><table summary="Navigation header" width="540" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><img src="http://docs.hp.com/img/s.gif" alt="spacer" width="1" height="1"></td><td><img src="http://docs.hp.com/img/s.gif" alt="spacer" width="1" height="1"></td><td><img src="http://docs.hp.com/img/s.gif" alt="spacer" width="1" height="1"></td></tr><tr class="decoration"><td colspan="3" bgcolor="#cccccc" height="1"><img src="http://docs.hp.com/img/s.gif" alt="spacer" width="1" height="1"></td></tr><tr class="decoration"><td colspan="3" bgcolor="#ffffff" height="4"><img src="http://docs.hp.com/img/s.gif" alt="spacer" width="1" height="4"></td></tr><tr><td valign="top" width="40%" align="left"><input class="primButton" value="«&nbsp;이전" name="btnPrev" type="submit">          &nbsp;        </td><th width="20%" align="center">          &nbsp;        </th><td valign="top" width="40%" align="right"><input class="primButton" value="다음&nbsp;»" name="btnNext" type="submit">          &nbsp;        </td></tr></tbody></table></div><div class="section" lang="ko"><p>Unified File Cache(UFC)는 페이지 캐시와 버퍼 캐시를 통합하여파일 액세스에 대해 일관성을 제공합니다. 현재 파일 시스템은 버퍼캐시를 사용하여 파일 데이터를 캐시하고 <tt class="function">mmap</tt>() 인터페이스는 페키지 캐시를 사용하여 파일 데이터를 캐시합니다.응용 프로그램에서 <span class="nowrap"><span class="citerefentry"><i class="refentrytitle">read</i>(2)</span></span>/<span class="nowrap"><span class="citerefentry"><i class="refentrytitle">write</i>(2)</span></span> 시스템 호출과 <span class="nowrap"><span class="citerefentry"><i class="refentrytitle">mmap</i>(2)</span></span>를동시에 사용하여 파일에 액세스하면 데이터가 두 캐시에 모두 있으므로HP-UX에서 일관성을 보장하지 않습니다. Unified File Cache를 사용하면일관성을 유지할 수 있습니다. 파일 데이터를 액세스하는 아키텍처를통합하면 파일 시스템에서 <tt class="function">read</tt>() 및 <tt class="function">write</tt>() 시스템 호출과 <tt class="function">mmap</tt>()에 대해 동일한 커널 인터페이스를 사용합니다. 이러한 공통인터페이스는 Solaris에서 타사 파일 시스템의 이식을 편리하게 합니다.</p><div class="section" lang="ko"><div class="titlepage"><div><div><table width="100%" border="0" cellpadding="0" cellspacing="1"><tbody><tr><td valign="top" align="left"><a name="d0e20627"></a><h3 class="bold"><span class="levelc">변경 사항요약</span></h3></td></tr><tr class="decoration"><td class="theme"><img src="http://docs.hp.com/img/s.gif" alt="" width="1" height="4"></td></tr></tbody></table></div></div></div><div class="section" lang="ko"><div class="titlepage"><div><div><a name="cacbabgj"></a><h4><span class="leveld">HP-UX11i v1(2005년 9월)에서 마이그레이션하는 고객을 위한 새로운 기능</span></h4></div></div></div><p>HP-UX 11i v3 이전에는 파일 시스템에서 버퍼 캐시를 사용하여파일 데이터를 캐시하고 <tt class="function">mmap</tt>() 인터페이스는 페키지 캐시를 사용하여 파일 데이터를 캐시합니다.응용 프로그램에서 read()/<tt class="function">write</tt>() system calls and <tt class="function">mmap</tt>()를 동시에 사용하여 파일에 액세스하면 데이터가 두 캐시에모두 있으므로 HP-UX에서 일관성을 보장하지 않습니다. Unified FileCache를 사용하면 일관성을 유지할 수 있습니다. 파일 데이터를 액세스하는아키텍처를 통합하면 파일 시스템에서 <tt class="function">read</tt>() 및 <tt class="function">write</tt>() 시스템 호출과 <tt class="function">mmap</tt>()에 대해 동일한 커널 인터페이스를 사용합니다. 이러한 공통인터페이스는 Solaris에서 타사 파일 시스템의 이식을 편리하게 합니다.</p></div><div class="section" lang="ko"><div class="titlepage"><div><div><a name="d0e20655"></a><h4><span class="leveld">HP-UX 11iv2(2006년 6월)에서 마이그레이션하는 고객을 위한 새로운 기능 </span></h4></div></div></div><p><a href="http://docs.hp.com/ko/5991-6472/ch06s16.html#cacbabgj" title="HP-UX11i v1(2005년 9월)에서 마이그레이션하는 고객을 위한 새로운 기능">“HP-UX11i v1(2005년 9월)에서 마이그레이션하는 고객을 위한 새로운 기능”</a>을 참조하십시오.</p></div></div><div class="section" lang="ko"><div class="titlepage"><div><div><table width="100%" border="0" cellpadding="0" cellspacing="1"><tbody><tr><td valign="top" align="left"><a name="d0e20661"></a><h3 class="bold"><span class="levelc">영향</span></h3></td></tr><tr class="decoration"><td class="theme"><img src="http://docs.hp.com/img/s.gif" alt="" width="1" height="4"></td></tr></tbody></table></div></div></div><p>HP-UX 11i v3의 Unified File Cache는 고객에게 다음과 같은 이점을제공하고 가치를 높입니다.</p><div><ul class="primarybullet"><li><div class="listitembody"><p class="list-initial">HP-UX 11i v3의기본 요구 사항인 VxFS 4.1 및 ONC+2.3의 주요 enabler 역할을 합니다. </p></div></li><li><div class="listitembody"><p class="list-initial">페이지 및 버퍼 캐시 일관성에종속된 Solaris, Tru64 및 Linux 응용 프로그램과의 소스 호환성을 향상시킵니다. </p></div></li><li><div class="listitembody"><p class="list-initial">또한 페이지 및 버퍼 캐시일관성에 종속된 응용 프로그램의 잠재적 성능이 향상됩니다. </p></div></li></ul></div></div><div class="section" lang="ko"><div class="titlepage"><div><div><table width="100%" border="0" cellpadding="0" cellspacing="1"><tbody><tr><td valign="top" align="left"><a name="d0e20676"></a><h3 class="bold"><span class="levelc">호환성</span></h3></td></tr><tr class="decoration"><td class="theme"><img src="http://docs.hp.com/img/s.gif" alt="" width="1" height="4"></td></tr></tbody></table></div></div></div><p>알려진 호환성 문제는 없습니다.</p></div><div class="section" lang="ko"><div class="titlepage"><div><div><table width="100%" border="0" cellpadding="0" cellspacing="1"><tbody><tr><td valign="top" align="left"><a name="d0e20681"></a><h3 class="bold"><span class="levelc">성능</span></h3></td></tr><tr class="decoration"><td class="theme"><img src="http://docs.hp.com/img/s.gif" alt="" width="1" height="4"></td></tr></tbody></table></div></div></div><p>페이지 및 버퍼 캐시 일관성에 종속된 응용 프로그램의 잠재적성능이 향상됩니다. 이러한 성능 향상은 응용 프로그램에 따라 달라집니다.</p></div><div class="section" lang="ko"><div class="titlepage"><div><div><table width="100%" border="0" cellpadding="0" cellspacing="1"><tbody><tr><td valign="top" align="left"><a name="d0e20686"></a><h3 class="bold"><span class="levelc">설명서</span></h3></td></tr><tr class="decoration"><td class="theme"><img src="http://docs.hp.com/img/s.gif" alt="" width="1" height="4"></td></tr></tbody></table></div></div></div><p>자세한 내용은 <span class="nowrap"><span class="citerefentry"><i class="refentrytitle">mmap</i>(2)</span></span> 맨페이지를 참조하십시오.</p></div><div class="section" lang="ko"><div class="titlepage"><div><div><table width="100%" border="0" cellpadding="0" cellspacing="1"><tbody><tr><td valign="top" align="left"><a name="d0e20697"></a><h3 class="bold"><span class="levelc">더 이상지원되지 않는 기능</span></h3></td></tr></tbody></table></div></div></div></div></div></td></tr></tbody></table><br />
			 ]]> 
		</description>
		<category>UNIX</category>

		<comments>http://altibase.egloos.com/2288724#comments</comments>
		<pubDate>Wed, 04 Mar 2009 02:00:31 GMT</pubDate>
		<dc:creator>오서비네</dc:creator>
	</item>
	<item>
		<title><![CDATA[ [펌] [사용성] COMMIT 과 SELECT 관계 정립 ]]> </title>
		<link>http://altibase.egloos.com/2283603</link>
		<guid>http://altibase.egloos.com/2283603</guid>
		<description>
			<![CDATA[ 
  altibase 는 현재 5.1.5.x 이하의 모든 버전 기준.<br />
FETCH LOOP 내에서 COMMIT / ROLLBACK 수행시 SELECT 결과 SET도 해제되는 문제가 있음.<br />
<br />
<br />
DB2 사례<br />
---------------------------<br />
From : http://publib.boulder.ibm.com/infocenter/db2luw/v8/index.jsp?topic=/com.ibm.db2.udb.doc/admin/r0000937.htm<br />
<h3 id="r0000937">DECLARE CURSOR <span>문 </span> </h3><div><a id="idx406" name="idx406"></a><a id="idx407" name="idx407"></a><a id="idx408" name="idx408"></a><a id="idx409" name="idx409"></a><a id="idx410" name="idx410"></a><a id="idx411" name="idx411"></a><a id="idx412" name="idx412"></a><a id="idx413" name="idx413"></a><a id="idx414" name="idx414"></a><a id="idx415" name="idx415"></a><a id="idx416" name="idx416"></a><a id="idx417" name="idx417"></a><a id="idx418" name="idx418"></a><a id="idx419" name="idx419"></a><a id="idx420" name="idx420"></a><a id="idx421" name="idx421"></a><a id="idx422" name="idx422"></a><a id="idx423" name="idx423"></a><a id="idx424" name="idx424"></a><a id="idx425" name="idx425"></a> </div><div><p>DECLARE CURSOR문은 커서를 정의합니다. </p> </div><div><span class="pblktitle">호출 </span><p>대화식 SQL 기능에서 대화식 실행의 형태를 나타내는 인터페이스를 제공하더라도,이 명령문은 응용프로그램 내에만 임베드될 수 있습니다. 이 명령문은 실행문이 아니며 동적으로 준비될 수 없습니다. </p> </div><div><span class="pblktitle">권한 부여 </span><p>이 용어는 『커서의 SELECT문』은 권한 부여 규칙을지정하는 데 사용됩니다.커서의 SELECT문은 다음 중 하나입니다.</p><ul><li><var class="pv">statement-name</var>에 의해 식별된 준비된 select문 </li><li>지정된 <var class="pv">select-statement</var> </li></ul><p>커서의 SELECT문에서 식별된(직접적으로 또는 별명을 사용하여)각 테이블 또는 뷰마다, 명령문의 권한 부여 ID로 보유되는특권에는 최소한 다음 중 하나가 포함되어야 합니다.</p><ul><li><var class="pv">select-statement</var>에 식별되는 각 테이블이나 뷰에 대해<ul><li>테이블이나 뷰에서의 SELECT 특권 또는 </li><li>테이블 또는 뷰에서의 CONTROL 특권 </li></ul> </li><li>SYSADM 또는 DBADM 권한 </li></ul><p> <span id="changed">4 </span><var class="pv">select-statement</var>에 SQL 데이터 변경문이 있는 경우<span id="changed">4 </span>해당 명령문의 권한 요구사항이 DECLARE CURSOR문에도 적용됩니다. </p><p><var class="pv">statement-name</var>이 지정된 경우:</p><ul><li>명령문의 권한 부여 ID는 런타임 권한 부여 ID입니다. </li><li>권한 부여 점검은 select문이 준비될 때 수행됩니다. </li><li>커서는 select문이 올바로 준비되지 않으면 열리지 않습니다. </li></ul><p><var class="pv">select-statement</var>이 지정된 경우:</p><ul><li>GROUP 특권이 점검되지 않습니다. </li><li>명령문의 권한 부여 ID는 프로그램 준비시 지정되는 권한 부여 ID입니다. </li></ul> </div><div><span class="pblktitle">구문 </span><pre class="cgraphic"><span><img src="http://publib.boulder.ibm.com/infocenter/db2luw/v8/topic/com.ibm.db2.udb.doc/admin/c.gif" alt="구문 도표 읽기" longdesc="db2s2_htmlsyn36.htm" border="0"></span><a href="http://publib.boulder.ibm.com/infocenter/db2luw/v8/topic/com.ibm.db2.udb.doc/admin/r0000937.htm#skipsyn-35"><img src="http://publib.boulder.ibm.com/infocenter/db2luw/v8/topic/com.ibm.db2.udb.doc/admin/c.gif" alt="시각적 구문 도표 생략" border="0"></a>&gt;&gt;-DECLARE--<span class="italic">cursor-name</span>--CURSOR--+-----------+------------------&gt;<br />
                                 '-WITH HOLD-'<br />
<br />
&gt;--+----------------------------+--FOR--+-<span class="italic">select-statement</span>-+---&gt;&lt;<br />
   |              .-TO CALLER-. |       '-<span class="italic">statement-name</span>---'<br />
   '-WITH RETURN--+-----------+-'<br />
                  '-TO CLIENT-'<br />
<br />
</pre><a name="skipsyn-35" id="skipsyn-35"></a> </div><div><span class="pblktitle">설명 </span><dl class="parml"><dt class="bold"><var class="pv">cursor-name</var> </dt><dd>소스 프로그램이 실행될 때 작성된 커서의 이름을 지정합니다.이름은 소스 프로그램에서 선언된 다른 커서의 이름과 동일해선 안됩니다.커서는 사용하기 전에 열려 있어야 합니다.</dd><dt class="bold">WITH HOLD </dt><dd>여러 작업 단위에서 자원을 유지보수합니다. WITH HOLD 커서 속성의 영향은 다음과 같습니다.<ul><li>COMMIT로 끝나는 작업 단위(UOW)의 경우<ul><li>WITH HOLD로 정의된 열린 커서는 열린 채로 있습니다. 커서는결과 테이블의 다음 논리 행 전에 위치됩니다. <p>DISCONNECT문이 WITH HOLD 커서를 갖는 연결에 대해 COMMIT문다음에 발행된 경우, 보유된 커서는 명시적으로 닫혀 있어야합니다. 그렇지 않으면, 연결은 작업을 수행한 것(SQL문이발행되지 않았어도 열린 WITH HELD 커서를 지님으로써)으로간주되어 DISCONNECT문이 실패하게 됩니다. </p> </li><li>열려 있는 WITH HOLD 커서의 현재 커서 위치를 보호하기위한 잠금을 제외한 모든 잠금이 해제됩니다.  테이블에 대한잠금과, 병렬 환경의 경우 커서가 현재 위치한 행에 대한잠금은 그대로 유지됩니다. 패키지와 동적 SQL 섹션(있을경우)에 대한 잠금은 그대로 유지됩니다. </li><li>다음은 COMMIT 요청 바로 다음에 오는 WITH HOLD 정의되는커서에 대한 유효한 조작입니다. <ul><li>FETCH:  커서의 다음 행을 페치합니다. </li><li>CLOSE:  커서를 닫습니다. </li></ul> </li><li>UPDATE 및 DELETE CURRENT OF CURSOR는 같은 작업 단위 내에서패치되는 행에 대해서만 유효합니다. </li><li>LOB 로케이터는 해제됩니다. </li><li> <span id="changed">4 </span>행 설정은 다음과 같이 수정됩니다.<span id="changed">4 </span><span id="changed">4 </span><ul><span id="changed">4 </span><li>데이터 변경문 </li><span id="changed">4 </span><li>열린 WITH HOLD 커서에 임베드된 SQL 데이터를 수정하는 루틴 </li></ul><span id="changed">4 </span>이 커미트됩니다. </li></ul> </li><li>ROLLBACK로 끝나는 작업 단위의 경우 <ul><li>열린 커서는 모두 닫힙니다. </li><li>작업 단위에서 획득된 모든 잠금은 해제됩니다. </li><li>LOB 로케이터는 해제됩니다. </li></ul> </li><li>특수 COMMIT의 경우 <ul><li>패키지는 패키지를 바인딩하여 명시적 또는 내재적으로재작성될 수 있습니다. 패키지의 유효성이 검사된 후 처음으로참조될 때 동적으로 재작성되었기 때문입니다. 패키지의리바인드중 보유된 모든 커서가 닫힙니다. 이는 후속 실행에서오류를 야기할 수도 있습니다. </li></ul> </li></ul></dd><dt class="bold">WITH RETURN </dt><dd>이 절은 커서가 프로시저로부터의 결과 세트로사용됨을 나타냅니다.WITH RETURN은 DECLARE CURSOR문이 프로시저의소스 코드와 함께 포함되는 경우에만 관련됩니다. 다른 경우에는프리컴파일러가 이 절을 사용할 수 있으나 아무 효과도 없습니다.<p>SQL 프로시저내에서 SQL 프로시저 종료시에도 여전히 열려 있는WITH RETURN절을 사용하여 선언된 커서는 SQL 프로시저로부터의결과 세트를 정의합니다.SQL 프로시저 내의 다른 모든 열린 커서는SQL 프로시저가 종료될 때 닫힙니다.외부 프로시저(LANGUAGE SQL을 사용하여 정의되지 않은) 내에서는 모든 커서의 디폴트가 WITH RETURN TO CALLER입니다.그러므로 프로시저를 종료할 때 열려 있는 모든 커서는 결과 세트로 간주됩니다. </p><dl><dt class="bold">TO CALLER </dt><dd>커서가 결과 세트를 호출자에게 리턴할 수 있도록 지정합니다. 예를 들어, 호출자가 다른 프로시저인 경우 결과 세트는 해당프로시저로 리턴됩니다. 호출자가 클라이언트 응용프로그램인 경우결과 세트는 클라이언트 응용프로그램으로 리턴됩니다.</dd><dt class="bold">TO CLIENT </dt><dd>커서가 결과 세트를 클라이언트 응용프로그램으로리턴할 수 있도록 지정합니다. 이 커서는 중간 중첩된 프로시저에게는 보이지 않습니다.함수나 메소드가 직간접적으로 프로시저를 호출한 경우에는결과 세트가 클라이언트에게 리턴되지 않고 프로시저가 완료되면 커서가 닫힙니다.</dd></dl></dd><dt class="bold"><var class="pv">select-statement</var> </dt><dd>커서의 SELECT문을 식별합니다.<var class="pv">select-statement</var>은 매개변수 표시문자를 포함해서는 안되나, 호스트 변수에 대한 참조는 포함할 수 있습니다.호스트 변수의 선언은 소스 프로그램에서 DECLARECURSOR문 앞에 있어야 합니다.</dd><dt class="bold"><var class="pv">statement-name</var> </dt><dd><var class="pv">statement-name</var> 커서의 SELECT문은 커서가 열릴 때명령문 이름으로 식별되는 준비된 SELECT문입니다. <var class="pv">statement-name</var>은 소스 프로그램의 다른 DECLARE CURSOR문에 지정된<var class="pv">statement-name</var>과 같으면 안됩니다.<p>prepared SELECT문에 대한 설명은 『PREPARE』를 참조하십시오. </p></dd></dl> </div><div id="decrnts"><span class="pblktitle">참고 </span><a name="csrdel"></a><ul id="csrdel"><li>다른 프로그램 또는같은 프로그램내의 다른 소스 파일로부터 호출되는 프로그램은 호출하는 프로그램이열어 놓은 커서를 사용할 수 없습니다. </li><li>SQL이 아닌 다른 LANGUAGE로 중첩되지 않은 프로시저는WITH RETURN절없이 DECLARE CURSOR가 지정되고 커서가 프로시저에서 열려 있는경우 디폴트 동작으로 WITH RETURN TO CALLER를 가지게 됩니다. 이는 이전 버전의프로시저로 하여금 리턴 결과 세트를 적용 가능한 클라이언트 응용프로그램으로리턴할 수 있는 호환성을 제공합니다. 이러한 동작을 피하려면 해당 프로시저에서열려 있는 모든 커서를 닫으십시오. </li><li>커서의 SELECT문에 CURRENT DATE, CURRENT TIME 또는 CURRENTTIMESTAMP가 포함되어 있으면, 이 특수 레지스터에 대한 모든참조사항은 각 FETCH에서 같은 각각의 날짜 시간 값을 생성합니다.이 값은커서가 열릴 때 결정됩니다. </li><li>데이터의 효율적인 처리를 위해, 데이터베이스 관리자는 리모트서버로부터 데이터를 검색할 때 읽기 전용 커서에 대해 데이터를블록화할 수 있습니다. FOR UPDATE절을 사용하면, 데이터베이스관리 프로그램에서 커서가 갱신 가능 여부를 쉽게 결정할 수있습니다. 갱신 가능성은 액세스 경로 선택을 결정할 경우에도사용됩니다. 커서가 위치지정된 UPDATE나 DELETE문에서사용되지 않을 경우 FOR READ ONLY로 선언되어야 합니다. </li><li>열린 상태의 커서는 결과 테이블과 그 테이블의 행에 상대적인위치를 지시합니다. 테이블은 커서의 SELECT문에 의해 지정된결과 테이블입니다. </li><li>커서는 다음 각각의 조건이 만족되는 경우 <span class="italic">삭제 가능 </span>합니다.<ul><li>외부 fullselect의 각 FROM절이 OUTER절을 사용하지 않고 하나의기본 테이블이나 삭제 가능 뷰를 식별하는 경우(중첩된 또는 공통 테이블 표현식이나별칭은 식별할 수 없습니다.) </li><li>외부 fullselect에 VALUES절이 포함되지 않는 경우 </li><li>외부 fullselect에 GROUP BY절 또는 HAVING절이 포함되지 않는 경우 </li><li>외부 fullselect에 선택 목록 내의 컬럼 함수가 포함되지 않는 경우 </li><li>외부 fullselect에 UNION ALL 예외가 있는 SET 조작(UNION,EXCEPT 또는 INTERSECT)이 포함되지 않는 경우 </li><li>외부 fullselect의 선택 목록에 DISTINCT가 포함되지 않는 경우 </li><li> <span id="changed">4 </span>외부 fullselect에 ORDER BY절이 포함되어 있지 않고(ORDER BY절이 뷰에 중첩되어 있는 경우라도)<span id="changed">4 </span>FOR UPDATE절은 지정되어 있지 않습니다. </li><li>select-statement에 FOR READ ONLY절이 포함되지 않는 경우 </li><li> <span id="changed">4 </span>외부 fullselect의 FROM 절에 <var class="pv">data-change-table-reference</var>가 포함되지 않는 경우 </li><li>다음 중 하나 이상이 만족되는 경우<ul><li>FOR UPDATE절이 지정됩니다. </li><li> <span id="changed">4 </span>STATICREADONLY 바인드 옵션이 YES가 아닌 경우<span id="changed">4 </span>해당 커서는 정적으로 정의됩니다. </li><li>LANGLEVEL 바인드 옵션이 MIA 또는 SQL92E인 경우 </li></ul> </li></ul><p>커서와 연관된 외부 fullselect의 선택 목록에 있는 컬럼은 다음 각각이 만족되는 경우 <span class="italic">갱신 가능 </span>합니다.</p><ul><li>커서가 삭제 가능한 경우 </li><li>컬럼이 기본 테이블의 컬럼을 해석하는 경우 </li><li>LANGLEVEL 바인드 옵션이 MIA이고, SQL92E 또는 선택문에 FOR UPDATE절이포함되는 경우(해당 컬럼을 FOR UPDATE절에 명시적으로 또는 내재적으로 지정해야 합니다). </li></ul><p>커서가 삭제 불가능한 경우, <span class="italic">읽기 전용 </span>입니다. </p><p>커서는 다음 조건의 각각이 만족되는 경우 <span class="italic">앰비규어스 </span>합니다.</p><ul><li>선택문이 동적으로 준비된 경우 </li><li>선택문에 FOR READ ONLY절 또는 FOR UPDATE절이 포함되지 않는 경우 </li><li>LANGLEVEL 바인드 옵션이 SAA1인 경우 </li><li>그렇지 않으면, 커서가 삭제 가능 커서의 조건을 만족하는 경우 </li></ul><p>앰비규어스 커서는 BLOCKING 바인드 옵션이 ALL인 경우 읽기 전용으로 간주되고,그렇지 않으면, 갱신 가능으로 간주됩니다. </p> </li><li>CLI를 사용하여 작성된 응용프로그램이 호출한 프로시저의커서는 클라이언트 응용프로그램으로 직접 리턴된 결과 세트를 정의하는데 사용될 수 있습니다. SQL 프로시저의 커서는 WITH RETURN절을 사용하여 정의된 경우에만호출하는 SQL 프로시저로 리턴될 수 있습니다. </li><li>WITH HOLD로 선언된 커서에서 직간접적으로 호출한 루틴에 선언된 커서는 WITH HOLD 옵션을 상속하지 않습니다.따라서 루틴의 커서가 명시적으로 WITH HOLD로 정의되어 있지 않으면 응용프로그램의COMMIT가 커서를 닫습니다.<p>다음 응용프로그램과 두 개의 UDF를 고려하십시오.</p><pre class="xmp">Application:<br />
<br />
   <span class="bold">DECLARE </span> APPCUR <span class="bold">CURSOR WITH HOLD FOR SELECT </span> UDF1() ...<br />
   <span class="bold">OPEN </span> APPCUR<br />
   <span class="bold">FETCH </span> APPCUR ...<br />
   <span class="bold">COMMIT </span><br />
<br />
UDF1:<br />
<br />
   <span class="bold">DECLARE </span> UDF1CUR <span class="bold">CURSOR FOR SELECT </span> UDF2() ...<br />
   <span class="bold">OPEN </span> UDF1CUR<br />
   <span class="bold">FETCH </span> UDF1CUR ...<br />
<br />
UDF2:<br />
<br />
   <span class="bold">DECLARE </span> UDF2CUR <span class="bold">CURSOR WITH HOLD FOR SELECT </span> UDF2() ...<br />
   <span class="bold">OPEN </span> UDF2CUR<br />
   <span class="bold">FETCH </span> UDF2CUR ... </pre> <p class="indatacontent">응용프로그램이 APPCUR 커서를 페치(fetch)한 후에는 세 커서가 모두 열려 있습니다.APPCUR 커서는 WITH HOLD로 선언되어 있기 때문에 응용프로그램이 COMMIT문을 발행할 때APPCUR 커서는 계속 열려 있습니다.그러나 UDF1에서는 UDF1CUR 커서가 WITH HOLD 옵션으로 정의되어 있지 않기 때문에UDF1CUR 커서가 닫힙니다.UDF1CUR 커서가 닫히면 해당 select문에 있는 모든 루틴 호출이 완료되고,최종 호출을 수신하도록 정의되어 있으면 최종 호출을 수신합니다.UDF2가 완료되면 UDF2CUR가 닫힙니다. </p> </li></ul> </div><div><span class="pblktitle">예: </span><p> <span class="italic">예1: </span>&nbsp;DECLARE CURSOR문은 커서 이름 C1을 SELECT의 결과와 연관시킵니다.</p><pre class="xmp">  EXEC SQL  <span class="bold">DECLARE </span> C1 <span class="bold">CURSOR FOR </span><br />
      <span class="bold">SELECT </span> DEPTNO, DEPTNAME, MGRNO<br />
    <span class="bold">FROM </span> DEPARTMENT<br />
      <span class="bold">WHERE </span> ADMRDEPT = 'A00'; </pre><p> <span id="changed">4 </span> <span class="italic">예 2: </span>&nbsp;<span id="changed">4 </span>EMPLOYEE 테이블을 변경하여, 연봉을 기초로 주급을 계산한<span id="changed">4 </span>WEEKLYPAY 컬럼을 추가한다고 가정하십시오.<span id="changed">4 </span>커서를 선언하여, 삽입되는 행에서 시스템 생성 컬럼 값을 검색합니다.<span id="changed">4 </span> </p><span id="changed">4 </span> <pre class="xmp">   EXEC SQL <span class="bold">DECLARE </span> C2 <span class="bold">CURSOR FOR </span><br />
<span id="changed">4 </span>     <span class="bold">SELECT </span> E.WEEKLYPAY<br />
<span id="changed">4 </span>     <span class="bold">FROM NEW TABLE </span><br />
<span id="changed">4 </span>       <span class="bold">(INSERT INTO </span> EMPLOYEE<br />
<span id="changed">4 </span>        <span class="bold">( </span>EMPNO, FIRSTNME, MIDINIT, LASTNAME, EDLEVEL, SALARY <span class="bold">) </span><br />
<span id="changed">4 </span>        <span class="bold">VALUES( </span>'000420', 'Peter', 'U', 'Bender', 16, 31842 <span class="bold">) AS </span> E; </pre> </div><div><div><span class="pblktitle">관련 참조 </span><ul><li><a href="http://publib.boulder.ibm.com/infocenter/db2luw/v8/topic/com.ibm.db2.udb.doc/admin/r0000879.htm">SELECT문</a> </li><li><a href="http://publib.boulder.ibm.com/infocenter/db2luw/v8/topic/com.ibm.db2.udb.doc/admin/r0000897.htm">CALL문</a> </li><li><a href="http://publib.boulder.ibm.com/infocenter/db2luw/v8/topic/com.ibm.db2.udb.doc/admin/r0000973.htm">OPEN문</a> </li><li><a href="http://publib.boulder.ibm.com/infocenter/db2luw/v8/topic/com.ibm.db2.udb.doc/admin/r0000975.htm">PREPARE문</a> </li></ul> </div><div><span class="pblktitle">관련 샘플 </span><ul><li><div><span class="pblktitle">COBOL </span><ul><li><a href="http://publib.boulder.ibm.com/infocenter/db2luw/v8/topic/com.ibm.db2.udb.doc/ad/samples/mfcobol/s-cursor-sqb.htm">cursor.sqb -- How to update table data with cursor statically (MF COBOL)</a> </li><li><a href="http://publib.boulder.ibm.com/infocenter/db2luw/v8/topic/com.ibm.db2.udb.doc/ad/samples/mfcobol/s-tabsql-sqb.htm">tabsql.sqb -- Demonstrates common table expressions using SQL (MF COBOL)</a> </li></ul> </div> </li><li><div><span class="pblktitle">C </span><ul><li><a href="http://publib.boulder.ibm.com/infocenter/db2luw/v8/topic/com.ibm.db2.udb.doc/ad/samples/c/s-fnuse-sqc.htm">fnuse.sqc -- How to use built-in SQL functions  (C)</a> </li><li><a href="http://publib.boulder.ibm.com/infocenter/db2luw/v8/topic/com.ibm.db2.udb.doc/ad/samples/c/s-tbinfo-sqc.htm">tbinfo.sqc -- How to get information at the table level (C)</a> </li><li><a href="http://publib.boulder.ibm.com/infocenter/db2luw/v8/topic/com.ibm.db2.udb.doc/ad/samples/c/s-tut_mod-sqc.htm">tut_mod.sqc -- How to modify table data (C)</a> </li><li><a href="http://publib.boulder.ibm.com/infocenter/db2luw/v8/topic/com.ibm.db2.udb.doc/ad/samples/c/s-tut_read-sqc.htm">tut_read.sqc -- How to read tables (C)</a> </li></ul> </div> </li><li><div><span class="pblktitle">C++ </span><ul><li><a href="http://publib.boulder.ibm.com/infocenter/db2luw/v8/topic/com.ibm.db2.udb.doc/ad/samples/cpp/s-fnuse-sqC.htm">fnuse.sqC -- How to use built-in SQL functions  (C++)</a> </li><li><a href="http://publib.boulder.ibm.com/infocenter/db2luw/v8/topic/com.ibm.db2.udb.doc/ad/samples/cpp/s-tbinfo-sqC.htm">tbinfo.sqC -- How to get information at the table level (C++)</a> </li><li><a href="http://publib.boulder.ibm.com/infocenter/db2luw/v8/topic/com.ibm.db2.udb.doc/ad/samples/cpp/s-tut_mod-sqC.htm">tut_mod.sqC -- How to modify table data (C++)</a> </li><li><a href="http://publib.boulder.ibm.com/infocenter/db2luw/v8/topic/com.ibm.db2.udb.doc/ad/samples/cpp/s-tut_read-sqC.htm">tut_read.sqC -- How to read tables (C++)</a> </li></ul> </div> </li></ul> </div><div><p>이 주제는 <cite>SQL 참조서, 볼륨 2</cite>를 참조하십시오. </p> </div> </div><br />
			 ]]> 
		</description>
		<category>DBMS</category>

		<comments>http://altibase.egloos.com/2283603#comments</comments>
		<pubDate>Thu, 26 Feb 2009 04:06:28 GMT</pubDate>
		<dc:creator>오서비네</dc:creator>
	</item>
	<item>
		<title><![CDATA[ [펌] [SOCKET-FAQ] 0. C에 의한 유닉스 소켓 프로그래밍 - 전체 목차 ]]> </title>
		<link>http://altibase.egloos.com/2280519</link>
		<guid>http://altibase.egloos.com/2280519</guid>
		<description>
			<![CDATA[ 
  <div class="readHeader">            <div class="titleAndUser">                <div class="title">                    <h4>From : http://forum.falinux.com/zbxe/?document_srl=447826&amp;mid=network_programming&amp;listStyle=&amp;cpage=</h4><br />
<br />
<h4><a href="http://forum.falinux.com/zbxe/?document_srl=447826">[SOCKET-FAQ] 0. C에 의한 유닉스 소켓 프로그래밍 - 전체 목차</a></h4>                </div>                                <div class="userInfo">                                            <div class="author"><span class="member_4"><img src="http://forum.falinux.com/zbxe/files/member_extra_info/image_mark/004/4.gif" alt="id: 장길석" title="id : 장길석" style="vertical-align: middle; margin-right: 3px;" border="0">장길석</span></div>                                    </div>                                            </div>            <div class="dateAndCount">                <div class="uri" title="게시글 주소"><a href="http://forum.falinux.com/zbxe/?document_srl=447826">http://forum.falinux.com/zbxe/?document_srl=447826</a></div>                <div class="date" title="등록일">                    <strong>2008.05.19</strong> 00:06:30 (*.105.125.81)                </div>                <div class="readedCount" title="조회수">2227</div>                                <div class="replyAndTrackback">                                        <div class="replyCount"><a href="http://forum.falinux.com/zbxe/?document_srl=447826&amp;mid=network_programming&amp;listStyle=&amp;cpage=#comment" title="댓글"><strong>0</strong></a></div>                                                        </div>                                            </div>                    </div>                                                                        <!--BeforeDocument(447826,4)--><p>소켓 프로그래밍에 대한 매우 좋은 글이 있어서 소개합니다. 저도 소켓 프로그래밍을 하다 보면 책으로는 해소할 수 없는 궁금한내용이 많습니다. 이렇게 간질간질한 곳을 시원하게 긁어 주는 "C에 의한 유닉스 소켓 프로그래밍 - FAQ" 라는 문서가 있어서앞으로 몇 회로 나누어 올리려 합니다.</p>  <div class="jwfs"><fieldset style="margin-left: 5px; margin-right: 5px; margin-bottom: 10px; padding-left: 10px; padding-right: 10px;"><legend>문서 정보</legend><ul><li>Archive-name: unix-faq/socket</li><li>Posting-Frequency: monthly</li><li>최근 수정일: 1997/12/21</li><li>URL: http://www.auroraonline.com/sock-faq/</li><li>한글판작성자: 안창선(csan@coresw.co.kr, http://genesis.yonsei.ac.kr/~kabin) </li></ul></fieldset></div>  <p>작성을 Vic Metcalfe, Andrew Gierth 와 이외 몇 분이 작성하고, 감사하게도 <strong>안창선</strong>(csan@coresw.co.kr)  이라는 분이 읽기 편하게 한글로 변역해 주셨습니다.</p>  <p>문서 정보에는 http://www.auroraonline.com/sock-faq/ 로 소개되어 있었습니다만 문서가 오래되서 인지 열리지 았습니다. 대신에 웹으로 검색해 보니 아래의 링크에서  FAQ 자료를 볼 수 있었습니다.</p>  <blockquote>    <p><a href="http://www.sbin.org/doc/unix-faq/sockets-faq.html" target="_blank">Unix Socket FAQ</a></p>  </blockquote>  <p>위 링크보다 더 최근의 문서와 더 활발한 활동을 하는 웹 페이지는 아직 모릅니다만 찾게되면 본 문서를 업데이트하겠습니다.</p>  <p>전체 목차를 보시면 과연 어떤 내용이 들어 있는지 한 눈에 아실수 있겠죠. 전체 목차입니다. 앞으로 문서를 모두 올리면 아래의 목차 모두에 링크를 걸어서 보다 편리하게 문서를 보실 수 있도록 하겠습니다.</p>  <p class="jwtitle">목차</p>  <ol><li><a href="http://forum.falinux.com/zbxe/?mid=network_programming&amp;document_srl=447832#1">일반 정보와 개념</a>      <ol><li><a href="http://forum.falinux.com/zbxe/?mid=network_programming&amp;document_srl=447832#11">이 FAQ에 대하여</a></li><li>    <a href="http://forum.falinux.com/zbxe/?mid=network_programming&amp;document_srl=447832#12">누구를 위한 FAQ 인가?</a></li><li>    <a href="http://forum.falinux.com/zbxe/?mid=network_programming&amp;document_srl=447832#13">소켓은 무엇인가?</a></li><li><a href="http://forum.falinux.com/zbxe/?mid=network_programming&amp;document_srl=447832#14">소켓은 어떻게 작동하는가?</a></li><li><a href="http://forum.falinux.com/zbxe/?mid=network_programming&amp;document_srl=447832#15">책에 있는 소스코드를 구할 수 있는데가 있는가?</a></li><li><a href="http://forum.falinux.com/zbxe/?mid=network_programming&amp;document_srl=447832#16">또 다른 정보들은 어디에서 구할 수 있는가?</a> </li></ol>    </li><li> <a href="http://forum.falinux.com/zbxe/?mid=network_programming&amp;document_srl=448212" target="_blank">클라이언트와 서버 양쪽에 관한 질문 (TCP/SOCK_STREAM)      </a>      <ol><li>  <a href="http://forum.falinux.com/zbxe/?mid=network_programming&amp;document_srl=448212#21">언제 상대방쪽 소켓이 끊겼는지 알 수 있는 방법이   있는가?</a></li><li> <a href="http://forum.falinux.com/zbxe/?mid=network_programming&amp;document_srl=448212#22">bind()의 두 번째 파라메터는 무엇인가?</a></li><li> <a href="http://forum.falinux.com/zbxe/?mid=network_programming&amp;document_srl=448212#23">주어진   서비스의 port번호를 얻는 방법은?</a></li><li><a href="http://forum.falinux.com/zbxe/?mid=network_programming&amp;document_srl=448212#24">bind() 가 실패 했을 때 소켓   디스크립터를 가지고 할 수 있는 일은?</a></li><li> <a href="http://forum.falinux.com/zbxe/?mid=network_programming&amp;document_srl=448212#25">정확하게 소켓을 닫는 방법은 무엇인가?</a></li><li> <a href="http://forum.falinux.com/zbxe/?mid=network_programming&amp;document_srl=448212#26">언제 shutdown()을 써야 하는가?</a></li><li> <a href="http://forum.falinux.com/zbxe/?mid=network_programming&amp;document_srl=448212#27">TIME_WAIT 상태에 대해 설명해   달라.</a></li><li> <a href="http://forum.falinux.com/zbxe/?mid=network_programming&amp;document_srl=448212#28">상대방쪽이 죽었는지 알아 내는데 왜 이렇게 오래 걸리나?</a></li><li><a href="http://forum.falinux.com/zbxe/?mid=network_programming&amp;document_srl=448212#29">select(),   non-blocking I/O 그리고 SIGIO의 잇점들은 무엇인가?</a></li><li><a href="http://forum.falinux.com/zbxe/?mid=network_programming&amp;document_srl=448212#210">read()가 EPROTO 를 리턴했다. 무엇인가?</a></li><li><a href="http://forum.falinux.com/zbxe/?mid=network_programming&amp;document_srl=448212#211">소켓 버퍼에 있는 내용을 강제로 전달   할 수 있는 방법은 없나?</a></li><li><a href="http://forum.falinux.com/zbxe/?mid=network_programming&amp;document_srl=448212#212">소켓 프로그래밍을 위한 라이브러리가 있는가?</a></li><li><a href="http://forum.falinux.com/zbxe/?mid=network_programming&amp;document_srl=448212#213">select는 데이터가   있다고 하는데 읽으면 0을 리턴한다?</a></li><li><a href="http://forum.falinux.com/zbxe/?mid=network_programming&amp;document_srl=448212#214">select() 와 poll()의 차이점은 무엇인가?</a></li><li><a href="http://forum.falinux.com/zbxe/?mid=network_programming&amp;document_srl=448212#215">어떻게   [this]를 소켓을 통해 보낼 수 있는가?</a></li><li><a href="http://forum.falinux.com/zbxe/?mid=network_programming&amp;document_srl=448212#216">TCP_NODELAY는 어떻게   사용하는가?</a></li><li><a href="http://forum.falinux.com/zbxe/?mid=network_programming&amp;document_srl=448212#217">Nagle 알고리즘은 어떤일을 하는 것인가?</a></li><li><a href="http://forum.falinux.com/zbxe/?mid=network_programming&amp;document_srl=448212#218">read() 와 recv()의 차이점은?</a></li><li><a href="http://forum.falinux.com/zbxe/?mid=network_programming&amp;document_srl=448212#219">send()/write()가 SIGPIPE 신호를 생성할 수 있던데. 이 신호를 무시하거나 EPIPE오류에 대한 검사를 하지 않고 다른 처리를 했을때의어떤 잇점이 있는가? 시그널을 잡는 잡는 함수 에 넘겨지는 어떤 유용한 파라미터가 있는가?</a></li><li>   <a href="http://forum.falinux.com/zbxe/?mid=network_programming&amp;document_srl=448212#220">chroot()후에 socket()이 실패했다. 왜 그런가?</a></li><li><a href="http://forum.falinux.com/zbxe/?mid=network_programming&amp;document_srl=448212#221">소켓 호출로 부터 전달되는 EINTR을 유지해야 하는 이유는   무엇인가?</a></li><li><a href="http://forum.falinux.com/zbxe/?mid=network_programming&amp;document_srl=448212#222">언제 나의 프로그램이 SIGPIPE 신호를 받게 되는가?</a></li><li><a href="http://forum.falinux.com/zbxe/?mid=network_programming&amp;document_srl=448212#223">소켓 예외는 있는가?   out-of-band데이타란 무엇인가?</a></li><li><a href="http://forum.falinux.com/zbxe/?mid=network_programming&amp;document_srl=448212#224">어떻게 완전한 내 시스템의 호스트이름인 (FQDN)을 얻을 수 있는가?</a></li></ol>    </li><li> <a href="http://forum.falinux.com/zbxe/?document_srl=448381#3">클라이언트 어플리케이션 만들기 (TCP/SOCK_STREAM)</a>      <ol><li><a href="http://forum.falinux.com/zbxe/?document_srl=448381#31">문자열을 인터넷 주소로 바꾸는   방법은?</a></li><li><a href="http://forum.falinux.com/zbxe/?document_srl=448381#32">firewall과 proxy서버를 통해서 클라이언트가 작동하도록 하려면 어떻게 하는가?</a></li><li><a href="http://forum.falinux.com/zbxe/?document_srl=448381#33">어떻게 서버가 accept()하지않았는데도 connect()가 성공할 수   있는가?</a></li><li><a href="http://forum.falinux.com/zbxe/?document_srl=448381#34">하나의 서버 이상을 사용하고 있을 때 왜 서버 주소를 가끔 잃어 버리는가?</a></li><li><a href="http://forum.falinux.com/zbxe/?document_srl=448381#35">connect()를 위한 타임아웃시간을 설정할 수 있는가?</a></li><li><a href="http://forum.falinux.com/zbxe/?document_srl=448381#36">클라이언트 프로그램에서 포트번호를 갖기 위해 bind()를 써야 하는가 아니면 시스템이 connect()호출에서 선택하도록 해야   하는가?</a></li><li><a href="http://forum.falinux.com/zbxe/?document_srl=448381#37">왜 서버가 동작하고 있지 않을 때 "connection   refused"라는 메시지가 나오는가?</a></li><li><a href="http://forum.falinux.com/zbxe/?document_srl=448381#38">소켓을 통해 들어오는 정보의 양을 모를 경우 어떻게 해야 하는가?   동적 버퍼를 사용할 수 있는 방법이 있는가?</a></li></ol>    </li><li><a href="http://forum.falinux.com/zbxe/?document_srl=448747" target="_blank">서버 만들기 (TCP/SOCK_STREAM)</a>      <ol><li><a href="http://forum.falinux.com/zbxe/?document_srl=448747#41">bind()할 때   "address already in use" 메시지가 나왔는데   무슨의미인가?</a></li><li><a href="http://forum.falinux.com/zbxe/?document_srl=448747#42">왜 소켓을 닫을 수 없는가?</a></li><li><a href="http://forum.falinux.com/zbxe/?document_srl=448747#43">내 서버를 데몬으로   만들려면?</a></li><li><a href="http://forum.falinux.com/zbxe/?document_srl=448747#44">한번에 여러 포트로부터 listen할 수 있는가?</a></li><li><a href="http://forum.falinux.com/zbxe/?document_srl=448747#45">SO_REUSEADDR 가   정확히 뭐하는 것인가?</a></li><li><a href="http://forum.falinux.com/zbxe/?document_srl=448747#46">SO_LINGER 가 정확히 뭐하는 것인가?</a></li><li><a href="http://forum.falinux.com/zbxe/?document_srl=448747#47">SO_KEEPALIVE   가 정확히 뭐하는 것인가?</a></li><li><a href="http://forum.falinux.com/zbxe/?document_srl=448747#48">포트 번호를 1024 이하로 bind()할 수   있는 방법은?</a></li><li><a href="http://forum.falinux.com/zbxe/?document_srl=448747#49">클라이언트의 주소와 호스트 이름을 알아내는 방법은?</a></li><li><a href="http://forum.falinux.com/zbxe/?document_srl=448747#410">나의 서버를 위한 포트번호를   어떻게 선택 해야 하는가?</a></li><li><a href="http://forum.falinux.com/zbxe/?document_srl=448747#411">SO_REUSEADDR 와 SO_REUSEPORT 의 차이는 무엇인가?</a></li><li><a href="http://forum.falinux.com/zbxe/?document_srl=448747#412">multi-homed server를 만드는 방법은?</a></li><li><a href="http://forum.falinux.com/zbxe/?document_srl=448747#413">한 번에 한 글짜식 읽는 방법은?</a></li><li><a href="http://forum.falinux.com/zbxe/?document_srl=448747#414">서버에서   exec()를 실행하고 그것에 소켓 I/O를 attach시키려고 하고 있다. 그런데 그것을 통하여 모든 그 데이터를 얻지 못하고 있다.   왜 그런가?</a></li></ol>    </li><li><a href="http://forum.falinux.com/zbxe/?mid=network_programming&amp;document_srl=449129#5" target="_blank">UDP/SOCK_DGRAM 어플리케이션 작성      </a>      <ol><li><a href="http://forum.falinux.com/zbxe/?mid=network_programming&amp;document_srl=449129#51">TCP대신에 UDP는 언제 사용하는가?</a></li><li><a href="http://forum.falinux.com/zbxe/?mid=network_programming&amp;document_srl=449129#52">"connected" 소켓과 "unconnected"소켓의 차이는 무엇인가?</a></li><li><a href="http://forum.falinux.com/zbxe/?mid=network_programming&amp;document_srl=449129#53">connect() 호출이 소켓의 수신에 영향을   주는가?</a></li><li><a href="http://forum.falinux.com/zbxe/?mid=network_programming&amp;document_srl=449129#54">"connected" UPD 소켓으로부터 어떻게 하면 ICMP error를 읽을 수 있는가?</a></li><li><a href="http://forum.falinux.com/zbxe/?mid=network_programming&amp;document_srl=449129#55">어떻게 UDP메시지가 수신 되었다는 것을 확신 할 수 있는가?</a></li><li><a href="http://forum.falinux.com/zbxe/?mid=network_programming&amp;document_srl=449129#56">UDP 메시지가 순서대로 도착했음을 확신할 수   있는가?</a></li><li><a href="http://forum.falinux.com/zbxe/?mid=network_programming&amp;document_srl=449129#57">얼마나 자주 un-ack된 메시지에대해서 재전송 해야 하는가?</a></li><li><a href="http://forum.falinux.com/zbxe/?mid=network_programming&amp;document_srl=449129#58">How come only   the first part of my datagram is getting<br />
        through?</a></li></ol>    </li><li> <a href="http://forum.falinux.com/zbxe/?mid=network_programming&amp;document_srl=449131" target="_blank">고급 소켓 프로그래밍      </a>      <ol><li><a href="http://forum.falinux.com/zbxe/?mid=network_programming&amp;document_srl=449131#61">현재의 소켓 프로그램을 비블록킹 모드로 바꾸는 방법은?</a></li><li><a href="http://forum.falinux.com/zbxe/?mid=network_programming&amp;document_srl=449131#62">connect()의 타임아웃을 설정하는 방법은? </a></li></ol>    </li><li><a href="http://forum.falinux.com/zbxe/?mid=network_programming&amp;document_srl=449133" target="_blank">예제 소스 코드</a><br />
      </li></ol>			 ]]> 
		</description>
		<category>UNIX</category>

		<comments>http://altibase.egloos.com/2280519#comments</comments>
		<pubDate>Sun, 22 Feb 2009 23:20:00 GMT</pubDate>
		<dc:creator>오서비네</dc:creator>
	</item>
	<item>
		<title><![CDATA[ [펌] 캐나다 - 남자의 출산휴가.. ]]> </title>
		<link>http://altibase.egloos.com/2280502</link>
		<guid>http://altibase.egloos.com/2280502</guid>
		<description>
			<![CDATA[ 
  [ 한국 - 2008년 12월 19일 버전 ]<br />
<br />
좀더 검색하니 "무급" 이 확실하내요.<br />
우리회사는 1일 유급, 2일 무급이니 평균이상 ㅋㅋ<br />
그래도,, 엄마의 50%가 일하는 세상을 향해서는 아직 갈길이 멀고 머내요.. 세금 많이 내야죠..<br />
<br />
"개정안에 따르면 아내가 출산한 남성 근로자에게 회사는 3일간 무급으로 출산휴가를 의무적으로 줘야 한다"<br />
<br />
--------------------------------------------<br />
안녕하세요. 기업애로종합지원센터입니다.<br />
문의하신 출산휴가에 대하여 답변해드리겠습니다.<br />
<br />
1. 출산 전후로 휴가를 90일의 휴가를 부여하는 출산 휴가 제도<br />
출산휴가제도에 대한 설명을 원하시는것 같은데, 출산 뿐만아니라 임신 16주 이후 유산 또는 사산에 대해서도 유급휴가를 부여하여야 합니다. 출산 기간 동안의 임금 중 <strong><span style="color: rgb(255, 0, 0);">60일분 통상임금에대해서는 사용자가 유급으로 지급</span></strong> 하여야 하는데, 남녀고용평등과 일가정양립지원에 관한 법률 18조에 따라 산전휴가급여등이 지급된 경우에는 그 금액의 한도에서 책임을 합니다.<br />
<br />
2. 태아검진시간허용, 유급<br />
모자보건법10조에 따라서 검진기간을 허용하고 해당시간의 임금을 삭감하여서는 안됩니다.<br />
<br />
3. 육아시간, 유급<br />
생후 1년미만의 유아를 가진 여성근로자가 청구하면 1일 2회 각 30분이상의 유급수유시간을 부여야하여야 합니다.<br />
<br />
4. 배우자출산휴가(남자에도 적용),무급<br />
배우자가 출산한 경우 30일 이내에 청구하면 3일간의 휴가를 부여함<br />
<br />
5. 육아휴직제(남성에도 적용)<br />
생후 3년미만의 영유아가 있는 근로자가 휴직을 신청할 경우 1년이내로 이를 부여야하여 합니다.<br />
<br />
이상 답변 내용과 관련하거나 추가 문의사항이 있으시면 저희 센터로 연락주시기 바랍니다.<br />
감사합니다.<br />
<br />
[출처 <u><span style="color: rgb(129, 0, 129);"><a href="http://helpbiz.korcham.net/consult/Operation/crope_read.asp?seq=14089">http://helpbiz.korcham.net/consult/Operation/crope_read.asp?seq=14089</a>&nbsp;]</span></u><br />
<br />
<br />
[ 캐나다 ]<br />
참고로 캐나다에서 학생? 신분인 내 친구는 와이프 출산하고 열심히 출석부 찍었음. 외국인은 미적용?? 학생 예외 ??<br />
<br />
From : http://wellbeingstory.blogspot.com/2008/12/blog-post_573.html<br />
<br />
<div id="header-wrapper"><div class="header section" id="header"><div class="widget Header" id="Header1"><div id="header-inner"><div class="titlewrapper"><h1 class="title"><a href="http://wellbeingstory.blogspot.com/">CANADA LIFE - O Canada</a></h1></div><div class="descriptionwrapper"><p class="description"><span>캐나다에 일상적인 자선적(自選)이야기, 건강 이야기, 이민/유학에 관한 조그만 정보</span></p></div></div></div></div></div><div id="crosscol-wrapper" style="text-align: center;"></div><!-- google_ad_section_start --><h2 class="date-header">2008년 12월 21일 일요일</h2><a name="5886698639201813200"></a><h3 class="post-title entry-title"><a href="http://wellbeingstory.blogspot.com/2008/12/blog-post_573.html">남자의 출산휴가</a></h3><div class="post-body entry-content"><a href="http://1.bp.blogspot.com/_DDSsCdHAEIo/SU7yE1dZyQI/AAAAAAAAABw/K-OIim_6jPE/s1600-h/%C3%AB%E2%80%9A%C2%A8%C3%AC%C5%BE%EF%BF%BD%C3%AC%C2%B6%C5%93%C3%AC%E2%80%9A%C2%B0.bmp"><img id="BLOGGER_PHOTO_ID_5282425577835972866" style="margin: 0px 0px 10px 10px; float: right; width: 219px; height: 320px;" alt="" src="http://1.bp.blogspot.com/_DDSsCdHAEIo/SU7yE1dZyQI/AAAAAAAAABw/K-OIim_6jPE/s320/%EB%82%A8%EC%9E%90%EC%B6%9C%EC%82%B0.bmp" border="0"></a><br />
<div>남자의 출산휴가<br />
<br />
한국에서도 남자에게 출산 휴가를 몇일 준다고 한는데, 휴가라고 하기에는 너무 짧은것 아닌가 생각이 든다.<br />
며칠전 주위 동료가 출산휴가를 간다며, 내년에 보자고 한다.<br />
(이느무 시키, 지가 애낞는것도 아닌데….. )<br />
그러면서 슬며시 나에게 하는말이 “자네도 애 한 두명 더 낳고 출산 휴가를 가지 그래 ?”<br />
<br />
여기서는 남자도 출산휴가를 누구 눈치없이 떳떳히 간다. 4개월은 100% 급여를 받고 그 이상 10개월 까지는 60% 급여를 받는다.<br />
가만히 생각하면 남자가 출산휴가를 가는것도 당연한것 같기도 하고,<br />
세월이 많이 변하여, 남자가 애낳는 시대가 된것 같다.<br />
<br />
애낳고 가사일까지 하는 그런 여자는 이제 찾아보기 힘든 시대에 살고 있어,<br />
여자가 애를 낳았으면, 남자는 그 뒷바라지를 하라는 것이다.<br />
밥하고 빨래하고 그리고 집안청소 등등<br />
한국남자 같으면야 대충 조금 도와주는척 하다가 놀기 바쁠것이지만, 여기서 그랬다간<br />
당장 이혼당하고 말것이다.<br />
<br />
남자가 요리하고 빨래하고 그리고 청소하는것이 보편화 되어있는 사회이다.<br />
(단 한국남자 제외하고)<br />
그리고 힘쓰는일, 잔디깍고, 낙엽치우고, 눈치우고, 집안팍 고치고 수리하고 또 아이들과 놀아주고 그리고 시간나면 가족동반으로 쇼핑하고….. ( 이러고 살고 싶을까 ? )<br />
<br />
여기 남자들은 이러고 산다………..<br />
<br />
사는 방식에 있어 차이가 조금 있지만, 그래도 이것을 당연하게 생각하며 생활하고 있다.<br />
( 불쌍한 넘들……….. )<br />
<br />
그래 나도 내년에 한명, 후년에 또 한명 아들,딸 한명씩 더 낳아 나도 출산 휴가좀 가야겠다고 와이프에게 애기했다가 되지게 욕먹었다.<br />
( 나는 이러고 산다……. )</div></div><span class="post-author vcard">작성자:<span class="fn">이 용</span></span><span class="post-timestamp">위치<a class="timestamp-link" href="http://wellbeingstory.blogspot.com/2008/12/blog-post_573.html" rel="bookmark" title="permanent link"><abbr class="published" title="2008-12-21T02:16:00-08:00">오전 2:16:00</abbr></a></span><br />
			 ]]> 
		</description>
		<category>낙서장</category>

		<comments>http://altibase.egloos.com/2280502#comments</comments>
		<pubDate>Sun, 22 Feb 2009 22:05:48 GMT</pubDate>
		<dc:creator>오서비네</dc:creator>
	</item>
</channel>
</rss>
