본문 바로가기

Oracle/Oracle testing

Test1. CLOB -> VARCHAR로 변경

테스트 환경 
OS : Oracle Enterprise Linux 5.5 (x64) ( Vmware )
DB : ORACLE 11g R2 Ent. 
Storage Type : Ext3 ( FileSystem )

기존 CLOB 데이터가 있는 대량의 데이터가 있다.
이 데이터를 어디서든 활용을 하기위해서 
데이터를 좀더 빠른 상태로 구축하기위한 DW 작업을 해야하는 상황이 왔다.

CLOB 을 개선해야하는 상황이다.

사실 난 개발하면서 CLOB을 별로 좋지 않게 생각을 했다.
개발에서도 단순하게 컬럼데이터를 가져오는 형태로 개발을 할수가 없다.
아무리 못해도 1줄이 더 가면 갔지 줄지는 않는다.

여하튼 내 상황에서는 

clob 데이터의 data length 를 확인해보니.
최대 6000 최소 2~300 ? 정도? 
평균 1000이 약간 안된다.(물론 Byte) 

그래서 결정했다.

1000바이트씩 자르기로 했다.
nvarchar 형태의 데이터니.

nvarchar2(2000) 으로 두고 기존 clob 데이터를 자르면서 그에 대한 시퀀스값을 만들었다.
그리고 1개의 데이터에 대해서 여러개의 row 생성해야하기에 테이블 하나에 1,2,3,4... .를 넣어서 
묻지마 조인을 했다.

                  select  idx

    ,seq

                       ,result

                 from ( select   seq

                                    ,case when ct_len  + 990 <= seq * 990 then null else 1 end hwpoint 

                                    ,substr(ct ,(seq -1) * 990 + 1 ,990)  result

                                    ,skey

                                from  (   select  row_number() over (partition by idx order by idx) seq

                                                     ,length(ct) ct_len

                                                     ,ct

                                                     ,idx

                                              From  ct, stNumber ) )

               where hwpoint = 1 ;                 


-  substrb 도 쓸만했으나 바이트로 자르고나서 다시 붙이니까 문자들이 종종 사라진다.
끝부분이 잘리면서 약간 안맞는듯하다.
-  substr 을 가지고 자르게 되면 unicode같은 경우는 byte 가 되니 약간의 여유를 두고 자르기를 했다. 난 990 으로. 자르기를 시도.

-  자르고 난뒤 not null 인 컨텐츠들만 select 하면 문제가 없을줄 알았는데 막상 자르니 null 이 아니다.
('fadsfadsf' 의 데이터를 substr을 하고 빈 값을 또 자르면 null 아니고 무언가 값이 자꾸 남아서 위처럼 case 문으로 자른 데이터 길이가 전체 데이터보다 작다 /크다로 구분해서 (hwpoint) select 를 했다.


결과.

위 처럼 데이터를 자르고나서 테이블에 넣고 기존에 clob 데이터와 비교를 했다.
물론 plan를 봐야겠다. 
DW작업이라 FTS 가 많을 터라. 인덱스도 없이 그냥 select 를 해서 읽혀지는 것을 보기로 했다.

case 1. - clob 데이터가 있는 테이블 full scan

Execution Plan

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

Plan hash value: 1602174258


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

| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |

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

|   0 | SELECT STATEMENT  |      | 29911 |  3037K|  1112   (1)| 00:00:16 |

|   1 |  TABLE ACCESS FULL| CT   | 29911 |  3037K|  1112   (1)| 00:00:16 |

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



Statistics

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

       1935  recursive calls

         12  db block gets

      30896  consistent gets

       2984  physical reads

          0  redo size

  102966406  bytes sent via SQL*Net to client

   48876214  bytes received via SQL*Net from client

      59824  SQL*Net roundtrips to/from client

         41  sorts (memory)

          0  sorts (disk)

      29911  rows processed


case 2. - nvarchar 로 자른 데이터가 있는 테이블 full scan

Execution Plan

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

Plan hash value: 530917727


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

| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |

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

|   0 | SELECT STATEMENT  |      |     1 |  1092 |   497   (1)| 00:00:07 |

|   1 |  TABLE ACCESS FULL| CT  |     1 |  1092 |   497   (1)| 00:00:07 |

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



Statistics

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

        338  recursive calls

          0  db block gets

       1365  consistent gets

       1327  physical reads

          0  redo size

        665  bytes sent via SQL*Net to client

        513  bytes received via SQL*Net from client

          1  SQL*Net roundtrips to/from client

          5  sorts (memory)

          0  sorts (disk)

          0  rows processed


뭐 당연한 결과다.
CLOB 부르는게 어찌 비용이 싸겠는가.
아무리 DW 지만 clob 은 이래저래 -_- 거시기 하다.