분류

2019년 12월 29일 일요일

생에 첫 캠핑하기 4. 조리 도구 구매 1차 - 프리머스 에센셜 1.3L

1. 버너 구매 기준

캠핑용 버너를 구매할 때 중요하게 생각한 것은 가격, 크기, 활용도 정도였습니다. 백패킹에 어울리게 작은 크기에, 2,3개의 코펠이 있으면 좋겠고, 손잡이가 걸리적거리지 않는 제품이 좋을 거라고 생각했습니다. 사용 연료는 가장 구하기 쉬운 가스. 겨울철 캠핑은 생각하지 않기에 고르는 것이 어렵지 않았습니다. 구매 고려 대상이었던 제품은 아래와 같습니다.

구분 리엑터스토브1.0 알파인마스터 에센셜 스토브
제조사 MSR 비전코베아 프리머스
크기 18.5 x 13.5 17.8 x 21.3 19.8 x 9
재질 알루미늄 알루미늄 알루미늄
용량 1.0 리터 2 리터 1.3리터
구성 포트1,스토브1 포트1, 스토브1
뚜껑 겸 후라이팬
포트2, 스토브1
뚜껑 겸 후라이팬
무게 595g 883g 858g
점화방식 수동 수동 수동
사용연료 가스 가스 가스
가격  ₩              257,140  ₩             189,000  ₩          121,486

역시 첫 번째 문제는 가격이었고, 그 다음은 활용도가 신경 쓰였습니다. 에센셜 스토브 세트를 선택하게 된 이유는 조리를 할 수 있는 그릇이 2개라는 점, 후라이팬이 있다는 점, 그리고 저렴하다는 점, 손잡이가 분리된다는 점 이었습니다.

최소 2인이 캠핑 할 것을 생각하니 2개의 그릇이 있다는 점이 매우 유용할 것으로 마음에 다가왔습니다. 즉석에서 만들 수 있는 간단한 요리를 2,3가지 준비할 수 있다는 점. 혹은 간결한 파스타나 냉동식품류를 먹을경우 각자의 그릇 필요없이 하나씩 놓고 먹으면 된다는 점 같은것 말이죠. 또한 손잡이가 분리되는 형태는 이전부터 테팔 주방용품을 쓰고있어서 매우 선호합니다.

2. 구매 


ebay에서 73$와 배송료 8$를 합쳐 81.6$가 들었으며 배송은 14일이 걸렸습니다. 국내에서도 약 12만원 가량에 에센셜 스토브 세트를 구매할 수 있지만, 내년 봄까지는 여유가 제법 있는 관계로 기간이 오래 걸리더라도 저렴한 편이 낫다고 생각했습니다.


박스포장은 제법 부실한 상태로 왔습니다. (금속 제품이기에 그냥 막 보낸 것 같기도 합니다. )


3. 외형 


제품 구성은 두개의 1.3리터 냄비와 뚜껑 겸용 후라이팬, 그리고 분리형 손잡이, 버너, 그리고 이상한 번쩍이는 알루미늄 판이 있는데 이건 ... 바닥에 놓는 용도라고 하는데 정확히는 모르겠습니다. 매우 유연한 것이 바람막이나, 바닥이 고르지 않을 경우 받침으로 활용하는 등의 여러 용도로 쓸 수 있을 것 같습니다.

다음은 각각의 사이즈입니다.
뚜껑이 185mm

스토브가 160mm

포트가 178mm
높이는 90mm입니다. 

포장용 파우치에 전부 넣고 무게를 확인하니 800g이 나옵니다. 스펙보다 약간 더 가볍습니다. 이 정도는 체중계의 오차범위 때문에 발생할 수 있는 것 같습니다.

4. 성능

성능은 물 끓이는 것 정도밖에 보여드릴 게 없는 것 같습니다. 공개된 스팩상 조리시간은 5분이라고 되어있습니다. 굳이 다른 제품들과 비교하자면 1리터의 물을 끓이는 경우 걸리는 시간이 아래와 같습니다.
------------------------------------
MSR 리엑터 스토브 4분07초
코베아 알파인마스터 2분42초
도토리묵 TV
-------------------------------
프리머스 에센셜 1.3L 7분30초 : 상온 18.9도 냉수 측정
500ml를 끓일 경우 3분 30초.
비싼게 괜히 비싼건 아닌 것 같습니다. 여유가 되면 리엑터 스토브도 구매 해봐야 할 것 같습니다.
-------------------------------

별거 없는 영상이지만 물 끓이는데 걸리는 시간을 체크하는 용도로 찍은 동영상 입니다.
음.. 중간에 분리형 손잡이의 단점 이라던가 화구를 잠깐 보여주기는 합니다. (분리형 손잡이가 꽉 잡지 못해서 약간 유격이 있습니다.. 그렇다고 조리에 지장이 있는 정도는 아닙니다. 아직은 부끄럼쟁이라 영상찍을때 말을 한다던가 액션을 취하지는 못하네요... )

이상입니다. 읽어주셔서 감사합니다.



생에 첫 캠핑하기 시리즈는 아래와 같이 구성되어 있으며 점점 추가될 예정 입니다.
생에 첫 캠핑하기 1. 사전조사
생에 첫 캠핑하기 2. 텐트 고르기
생에 첫 캠핑하기 3. 반고 미스트랄 300 개봉기
생에 첫 캠핑하기 4. 조리 도구 구매 1차 - 프리머스 에센셜 1.3L

2019년 12월 9일 월요일

ORACLE WITH문 성능지연 개선사례

1. 성능지연현상 설명

최근 1년간 기존의 시스템 환경을 유지보수 하는 일을 하고 있습니다. 여러 SQL처리 문제점 중 WITH문이기에 발생하는 문제점도 종종 있는데 이번에 쓸 내용은 오라클이 TEMP SPACE를 사용하면서 원래는 인덱스에 의해 적절히 처리되거나,  필터나 함수에 의해 처리 돼야 할 부분까지 뻥튀기 되는 현상입니다.

솔직히 저도 이런 현상을 보는 것이 처음이고 이런 형태의 SQL을 사용하는 경우도 처음 보는 일입니다. 현상에 대한 구현도 간단하고, 처리도 간단한 편입니다. 그리고 시연도 간단합니다.

참고로 ORACLE 10g 10.2.0.4.0버전입니다.

기본적인 처리 방법으로는 이러한 connect by 를 불필요하게 2회 이상 반복하는 것 자체를 없애는 것이 답이지만, 경우에 따라 connect by 된 데이터에 데이터 일부를 추가해서 보여주는 경우가 발생하기에 어쩔 수 없이 쓰는 경우가 있습니다. 그런데 그렇더라도 union all 만 한번 하면 되는 것인데... 왜 저렇게 짰는지 제 지능으로는 도무지 이해가 가지 않습니다.

2. FULL SCAN 발생 SQL 및 실행계획

가) SQL

WITH TBL1 AS (
    SELECT * FROM (
        SELECT NULL AS COL1, 2 AS COL2, 3 AS COL3 FROM DUAL
          UNION ALL 
        SELECT 2 AS COL1, 2 AS COL2, 2 AS COL3 FROM DUAL
     ) START WITH COL1 IS NULL 
         CONNECT BY PRIOR COL1 = COL2 
)
SELECT * FROM TBL1 CONNECT BY COL2 = COL3 

나) 실행계획

- SELECT STATEMENT ALL_ROWS (cost : 6 bytes : 18 Cardinality : 2) 
  20 - TEMP TABLE TRANSFORMATION 
    15 - LOAD AS SELECT 
      14 - CONNECT BY WITH FILTRING
         6 - FILTER
           5 - (*) COUNT
              4 VIEW (Cost 4 Byte 18 Cardinality 2)
                3 - UNION ALL
                    1 FAST DUAL (Cost 2 Cardinality 1)
                    2 FAST DUAL (Cost 2 Cardinality 1)
         13 - HASH JOIN
               7 - CONNECT BY PUMP 
           12 - (*) COUNT
              11 VIEW (Cost 4 Byte 18 Cardinality 2)
                10 - UNION ALL
                    8 FAST DUAL (Cost 2 Cardinality 1)
                    9 FAST DUAL (Cost 2 Cardinality 1)
  20 - TEMP TABLE TRANSFORMATION 
     18 - (*) COUNT
        17 VIEW (Cost 4 Byte 18 Cardinality 2)
           16 TABLE ACCESS FULL TABLE(TEMP)SYS.SYS_TEMP_5DE.......
               (Cost 4 Byte 18 Cardinality 2)

작성된 SQL만으로 봐서는 ()안에 첫 with문을 넣고 with를 제외한 것과 with문에 넣은 것에 전혀 차이가 없어 보이지만, 동작하는 부분에서는 제법 차이가 납니다. 원인은 뭐... 옵티마이저 문제라고 해야 할까요? ;

지금이야 단 2건의 데이터가 있는 SQL을 작성했기에 성능에 영향을 주지 않겠지만, 데이터가 만 건 단위가 넘어가면서 부터 성능상의 문제가 발생하기 시작합니다.

운영 중인 시스템에선  실제로 약 4만건,20만건이 있는 테이블간의 레벨링을 수행하고 있었는데 실행 계획상 처리 비용은 (cost : 23,844 bytes : 206,185,688 Cardinality : 45,236) 이 발생하여 동시접속자가 500명만 되더라도 해당 SQL이 공유 메모리풀과 TEMPSPACE를 모두 차지하여 EXTENSION이 발생했고 해당 TEMPSPACE의 확장이 완료되기 전까지 약 30여분간 모든 서비스의 지연이 발생하곤 했습니다.  또한 시스템에서는 MR LOCKING. 즉 media recovery가 발생했습니다. 미디어 리커버리는 디스크의 이상 상황에 발생한다고 하는데... 확장영역을 충분히 얻지 못하거나 확장이 정상적으로 처리되지 않은 경우에도 발생하는 것 같습니다.

비용은 그렇다 쳐도 bytes 약 200MB 500명이면 약100GB의 메모리를 사용해야 합니다. 하나의 데이터만 제공하는 시스템이 아니기에 shared pool의 점유, 그리고 tempspace 대부분이 점유되면 모든 서비스의 지연이 일어납니다. TEMPTABLESPACE 가 작게 설정되어있다면 확장이 일어나게 되며, 확장이 완료될 때 까지 확장에 의한 지연이 발생 하기도 합니다. 게다가 지연이 발생하는 상황속에서 접속하는 추가 사용자 까지 합산한다면 용량은 점점 더 커지겠죠.

이러한 특성은 WITH문의 문제점으로 보입니다. 현재 사용하는 버전인 10G에서는 WITH문 괄호()안에 아무리 제약조건을 잘 걸어 두어도 with를 CONNECTION BY  조인하거나, 혹은 절차 처리를 하기 위해 다수의 with테이블이 상호 참조 관계가 발생 할 경우 with내에 선언된 테이블을 FULL SCAN 해서 시스템에 부하를 주는 SQL로 변질됩니다. 답은 빠른 응답이 필요한 프로그램의 경우 with문을 사용하지 않는 것이 좋은 것 같습니다.


3. 문제해결 

문제 해결 방법은 매우 간단했습니다. temp스페이스를 더 이상 이용하지 않게 만들면 되니, with절에 들어있는 SQL을 ()안에 넣어주면 될 일입니다. 

SELECT * FROM (
      SELECT * FROM (
        SELECT NULL AS COL12 AS COL23 AS COL3 FROM DUAL
          UNION ALL 
        SELECT 2 AS COL12 AS COL22 AS COL3 FROM DUAL
     START WITH COL1 IS NULL 
         CONNECT BY PRIOR COL1 = COL2 
)
CONNECT BY COL2 = COL3 

나) 실행계획

SELECT STATEMENT ALL_ROWS (cost : 4 bytes : 18 Cardinality : 2) 
  17 - CONNECT BY WITHOUT FILTERING 
    16 - (*) COUNT
      15 - VIEW....
          14 - CONNECT BY WITHOUT FILTERING 
             6 - FILTER
                5 - (*) COUNT
                  4 VIEW (Cost 4 Byte 18 Cardinality 2)
                     3 - UNION ALL
                        1 FAST DUAL (Cost 2 Cardinality 1)
                         2 FAST DUAL (Cost 2 Cardinality 1)
         13 - HASH JOIN
              7 - CONNECT BY PUMP 
             12 - (*) COUNT
                11 VIEW (Cost 4 Byte 18 Cardinality 2)
                10 - UNION ALL
                    8 FAST DUAL (Cost 2 Cardinality 1)
                    9 FAST DUAL (Cost 2 Cardinality 1)

고작 2건의 가상데이터에서도 table full scan 이 사라지며 비용이 2가량 감소합니다. 실제 운영 시스템에서는 (cost : 48 bytes : 18,232 Cardinality : 4)로 사용 메모리양이 1/10000 가량 줄어들게 되었습니다. full scan때문에 불가능했던 index 전략도 정상적으로 처리되었기 때문이죠. 또한 위와 아래의 plan을 비교해보면 table full scan이 굳이 필요한가 싶기도 합니다. 뭐... 옵티마이저님 하시는 일을 일개 인간인 제가 어찌 알겠습니까...

이상입니다. 읽어주셔서 감사합니다.