달력

42026  이전 다음

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

04. Array Processing 활요

  • Array Processing 기능을 활용하면 한 번의 SQL 수행으로 다량의 로우를 동시에 insert/update/delete 할 수 있다.
  • 네트워크를 통한 데이터베이스 Call을 감소시켜주고, 궁극적으로 SQL 수행시간과 CPU 사용량을 획기적으로 줄여준다.

사례1 ? Java 프로그렘에서 Array Processing)

public class JavaArrayProcessing{ 
  public static void insertData( Connection con 
                               , PreparedStatement st 
                               , String param1 
                               , String param2 
                               , String param3 
                               , long param4) throws Exception{ 
    st.setString(1, param1); 
    st.setString(2, param2); 
    st.setString(3, param3); 
    st.setLong(4, param4); 
    *st.addBatch();* 
  } 
 
  public static void execute(Connection con, String input_month)  
  throws Exception { 
    long rows = 0; 
    String SQLStmt1 = "SELECT 고객번호, 납입월" 
                    + "     , 지로, 자동이체, 신용카드, 핸드폰, 인터넷 " 
                    + "FROM   월요금납부실적 " 
                    + "WHERE  납입월 = ?"; 
                    
    String SQLStmt2 = "INSERT /*+ test3 */ INTO 납입방법별_월요금집계  "  
            + "(고객번호, 납입월, 납입방법코드, 납입금액) " 
            + "VALUES(?, ?, ?, ?)"; 
 
    con.setAutoCommit(false); 
 
    PreparedStatement stmt1 = con.prepareStatement(SQLStmt1); 
    PreparedStatement stmt2 = con.prepareStatement(SQLStmt2); 
    *stmt1.setFetchSize(1000);* 
    stmt1.setString(1, input_month); 
    ResultSet rs = stmt1.executeQuery(); 
    while(rs.next()){ 
      String 고객번호 = rs.getString(1); 
      String 납입월 = rs.getString(2); 
      long 지로 = rs.getLong(3); 
      long 자동이체 = rs.getLong(4); 
      long 신용카드 = rs.getLong(5); 
      long 핸드폰 = rs.getLong(6); 
      long 인터넷 = rs.getLong(7); 
      if(지로 > 0)     insertData (con, stmt2, 고객번호, 납입월, "A", 지로); 
      if(자동이체 > 0) insertData (con, stmt2, 고객번호, 납입월, "B", 자동이체); 
      if(신용카드 > 0) insertData (con, stmt2, 고객번호, 납입월, "C", 신용카드); 
      if(핸드폰 > 0)   insertData (con, stmt2, 고객번호, 납입월, "D", 핸드폰); 
      if(인터넷 > 0)   insertData (con, stmt2, 고객번호, 납입월, "E", 인터넷); 
      *if(++rows%1000 == 0) stmt2.executeBatch();* 
    } 
 
    rs.close(); 
    stmt1.close(); 
 
    *stmt2.executeBatch();* 
    stmt2.close(); 
 
    con.commit(); 
    con.setAutoCommit(true); 
  } 
 
  public static void main(String[] args) throws Exception{ 
    long btm = System.currentTimeMillis(); 
    Connection con = getConnection(); 
    execute(con, "200903"); 
    System.out.println("elapsed time : " + (System.currentTimeMillis() - btm)); 
    releaseConnection(con); 
} 
 
- 트레이스 결과 
 
SELECT 고객번호, 납입월, 지로, 자동이체, 신용카드, 핸드폰, 인터넷 
FROM 월요금납부실적 WHERE 납입월 = :1 
 
 
call     count       cpu    elapsed       disk      query    current        rows 
------- ------  -------- ---------- ---------- ---------- ----------  ---------- 
Parse        1      0.00       0.00          0          0          0           0 
Execute      1      0.01       0.01          0         71          0           0 
Fetch       31      0.00       0.04          0        169          0       30000 
------- ------  -------- ---------- ---------- ---------- ----------  ---------- 
total       33       0.01      0.04          0         240          0       30000 
 
Misses in library cache during parse: 1 
Misses in library cache during execute: 1 
Optimizer mode: ALL_ROWS 
Parsing user id: 54 
 
Rows     Row Source Operation 
-------  --------------------------------------------------- 
  30000  TABLE ACCESS FULL 월요금납부실적 (cr=169 pr=0 pw=0 time=90083 us) 
 
 
INSERT INTO 납입방법별_월요금집계  
(고객번호, 납입월, 납입방법코드, 납입금액) 
VALUES (:1 , :2 , :3 , :4 ) 
 
 
call     count       cpu    elapsed       disk      query    current        rows 
------- ------  -------- ---------- ---------- ---------- ----------  ---------- 
Parse        1      0.00       0.00          0          0          0           0 
Execute     30      0.18       0.27          2        923       5094      150000 
Fetch        0      0.00       0.00          0          0          0           0 
------- ------  -------- ---------- ---------- ---------- ----------  ---------- 
total        31      0.18       0.27          2        923       5094      150000 
 
Misses in library cache during parse: 1 
Misses in library cache during execute: 1 
Optimizer mode: ALL_ROWS 
Parsing user id: 54
  • 150,000(30,000*5)건을 insert 하는데 단 1.21초 만에 수행
  • insert 문에 대한 Execute Call이 30회만 발생
  • insert 된 로우 수가 150,000건이므로 매번 5,000건씩 Array Processing한 것.
    (커서에서 Fetch되는 각 로우마다 5번씩 insert를 수행하는데, 1,000 로우마다 한번식 executeBatch를 수행하기 때문)
  • select 결과를 Fetch 할 때도 1,000개 단위로 Array Fetch 하도록 조정. (JAVA에서 기본값은 10)
  • 30,000건을 읽는데 Fetch Call이 31회만 발생.

  • 네트워크를 경유해 발생하는 데이터베이스 Call이 얼마맡큼 심각한 성능부하를 일으키는 지 ?수 있다.
  • One-SQL로 통합하지 않더라도 Array Processing 만으로 그에 버금가는 성능개선 효과를 얻을 수 있다.
  • Array Processing의 효과를 극대화하려면 연속된 일련의 처리과정이 모두 Array 단위로 진행 되어야 한다.

사례2 ? PL/SQL Bulk insert

DECLARE 
  l_fetch_size NUMBER DEFAULT 1000;  -- 1,000건씩 Array 처리 
 
  CURSOR c IS  
    SELECT empno, ename, job, sal, deptno, hiredate  
    FROM   emp; 
 
  TYPE array_empno      IS TABLE OF emp.empno%type; 
  TYPE array_ename      IS TABLE OF emp.ename%type; 
  TYPE array_job        IS TABLE OF emp.job%type; 
  TYPE array_sal        IS TABLE OF emp.sal%type; 
  TYPE array_deptno     IS TABLE OF emp.deptno%type; 
  TYPE array_hiredate   IS TABLE OF emp.hiredate%type; 
 
  l_empno     array_empno     := array_empno   (); 
  l_ename     array_ename     := array_ename   (); 
  l_job       array_job       := array_job     (); 
  l_sal       array_sal       := array_sal     (); 
  l_deptno    array_deptno    := array_deptno  (); 
  l_hiredate  array_hiredate  := array_hiredate(); 
 
  PROCEDURE insert_t( p_empno     IN array_empno    
                    , p_ename     IN array_ename    
                    , p_job       IN array_job      
                    , p_sal       IN array_sal      
                    , p_deptno    IN array_deptno   
                    , p_hiredate  IN array_hiredate ) IS 
 
  BEGIN 
    *FORALL i IN p_empno.first..p_empno.last* 
      *INSERT INTO emp2* 
      VALUES ( p_empno   (i) 
             , p_ename   (i) 
             , p_job     (i) 
             , p_sal     (i) 
             , p_deptno  (i) 
             , p_hiredate(i) ); 
 
  EXCEPTION 
    WHEN others THEN 
      DBMS_OUTPUT.PUT_LINE(SQLERRM); 
      RAISE; 
  END insert_t; 
 
BEGIN 
 
  OPEN c; 
 
  LOOP 
 
    *FETCH c BULK COLLECT* 
    *INTO l_empno, l_ename, l_job, l_sal, l_deptno, l_hiredate* 
    *LIMIT l_fetch_size;* 
 
    insert_t( l_empno, l_ename, l_job, l_sal, l_deptno, l_hiredate ); 
 
    EXIT WHEN c%NOTFOUND; 
  END LOOP; 
 
  CLOSE c; 
 
  COMMIT; 
 
EXCEPTION 
  WHEN OTHERS THEN 
    ROLLBACK; 
END; 
/
  • SQL 트레이스 결과를 보면, 10,000건을 처리하는데 select문의 Fetch Call과 insert문의 Execute Call이 각각 10번씩만 발생한 것을 알 수 있다.
    (select의 Fetch Call이 11번이 발생한 것은 데이터가 더 있는지 확인하기 위한 것임)
  • EXP, IMP 명령을 통해 데이터를 Export, Import 할 때도 내부적으로 Array Proccessing이 활용
    (buffer 옵션으로 지정가능, byte 단위로 지정 = rows_in_array * maximum_row_size)
  • Array Processing을 지원하는 인터페이스가 프로그램 언어별로 각기 다르므로 API를 통해 확인하고 이를 활용할 것.

문서에 대하여

  • 최초작성자 : [김종원]
  • 최초작성일 : 2010년 01월 09일
  • 이 문서는 오라클클럽 코어 오라클 데이터베이스 스터디 모임에서 작성하였습니다.
  • 이 문서의 내용은 (주)비투엔컬설팅에서 출간한 '오라클 성능 고도화 원리와 해법I'를 참고하였습니다.

# 이 문서는 
오라클클럽에서 작성하였습니다. 
# 이 문서를 다른 블로그나 홈페이지에 게재하실 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^^ 
# 출처 : 
http://wiki.oracleclub.com/pages/viewpage.action?pageId=3901805&
Posted by InuxKr
|
Signed Applet 을 개발할 경우 개발단계에서는

keytool 을 통해 key를 생성하고 jarsigner 를 통해 jar 파일에 서명을 해서 사용한다

이후 인증서를 구매하게되면 해당 인증서로 jar에 서명을 하면된다

인증서를 구매할 경우 keytool 은 사용할 필요가 없으며 jarsigner 만 사용하면된다


jar -cvf xxx.jar kr  
   kr 패키지의 하위 패키지를 xxx.jar 로 패키지 작성

jarsigner -keystore xxx.jks -storepass xxxx CheckVerLoader2.jar hts
   -keystore : 저장소의 위치, 인증서로 받은 xxx.jks 파일의 절대 혹은 상대경로
   -storepass : 인증서의 패스워드
   hts :  인증서의 alias 명

alias 를 모를경우  keytool 을 사용하면된다
keytool -list -v -keystore xxx.jks
Posted by InuxKr
|
이 작업은 정상적인 방법으로는 불가능하다

하지만 Log4J 등의 로그를 보면 현재 실행중인 메서드를 찍어준다

예전에 HeadFist Java에서 봤던가? 

원하는 위치에서 Exception 을 강제로 발생시키고 해당 에러의 printStackTrace() 를 이용한다고 알고 있었는데 생각난김에 코드를 찾아보았다

방법1)
Throwable t = new Throwable();
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
t.printStackTrace(pw);
String input = sw.getBuffer().toString();
StringReader sr = new StringReader(input);
BufferedReader br = new BufferedReader(sr);
br.readLine(); // Exception name
String line = br.readLine();
int paren = line.indexOf('(');
line = line.substring(0, paren);
int period = line.lastIndexOf('.');
line = line.substring(period + 1);
System.out.println("Method: " + line);

방법2)
Throwable t = new Throwable();
StackTraceElement elements[] = t.getStackTrace();
String method = elements[0].getMethodName();
System.out.println("Method: " + method);


방법1 은 printStackTrace 의 전체 출력내용중 처음부터 첫 ( 문자까지 자르고  그 잘라낸 문자열 중 첫 . 이후까지를 잘라서 추출한다 (아래 중 굵은 글씨만 추출)

java.lang.Throwable
at Test.testMethod1(Test.java:15)
at Test.main(Test.java:10)


Posted by InuxKr
|
매번 구글링&네이년 하다가 적어놓음

svnadmin create --fs-type fsfs [상대|절대 경로]
ex) svnadmin create --fs-type fsfs test     # test 라는 repository 추가

[conf 파일 수정]
passwd : id = pw
   ex) test = 1234 # id : test  pw : 1234 인 유저 생성

svnserve.conf 

anon-access = none # anonymous user 접근금지
auth-access = write # 인증된 사용자 쓰기권한
password-db = passwd # 계정정보 파일명
realm = My First Repository # 마음대로 repository 정보
Posted by InuxKr
|

IPA(India Pale Ale)

MicroBrewery 2009. 7. 9. 17:01

올해 두번째 작업 IPA

7월 6일 오스트리안마인드 작업후 모아놓은 슬러지를 꺼내놓음(아메리칸 에일 효모 3세대)

7월 7일 
퇴근후 장비들을 소독해놓고 식사후 바로 작업을 시작하려했으나
운동을 하러나가는 바람에 작업시작이 좀 지체되었다

보통 정석은 캔속의 원액과 스프레이몰트를 모두 끓인후 찬물을 넣고 식혀야되나
시간도 늦었고 귀찮은 관계로 그냥 한주전자 정도의 끓인물 만을 준비하고
원액이 발효조 바닥에 엉겨붙지 않게 먼저 발효조에 약간의 물을 넣고 원액을 부은후
뜨거운물로 용기속에 남은 원액을 깨끗하게 닦아 붓고
미지근한 워트에 바로 스프레이몰트 2봉(1kg)을 투입

여기서 생기는 문제.... 원액은 어차피 기본 액체상태라 문제가 안되는데  
원액과 스프레이몰트가 같이 엉기면서 굳은 덩어리들이 생겨버린다

젠장.....스프레이몰트라도 다 녹이고 원액을 넣던가 했어야하는데
별수없이 패들로 힘차게 저어서 가능한만큼 최대한 녹였다
에어레이션은 엄청 잘되었을듯하다
100%는 아니고 꽤 많이 녹은하여 마무리. 

나머지 엉긴덩어리들은 발효가 되면서 잘 녹아들길...

비중을 재어봤더니 1.050이 나왔다 평소랑 물양도 비슷한데 0.010 이 더 높게 나왔다
IPA 가 원래 당도가 높게나오는가 싶어서 찾아봤는데 그것도 아닌듯하고...
정확히 측정이된거라면 5.2도가량의 약간 더 높은 도수가 나오리라 보인다
어차피 IPA는 도수를 좀 높이는게 좋다고하니 약간 높게 나온김에 스프레이몰트를 한본 더 쓰면 좋을듯하나 아까 찬물에 원액+스프레이몰트를 같이 투입해서 엉겨버린 삽질때문에 그냥 진행

하루정도 상온에 꺼내놓은 슬러지가 나름 활성화가 잘되어있는 상태다
플라스틱 뚜껑을 열어보니 물에 녹아있던 탄산이 확 방출되면서 가라앉았던 슬러지까지 확 뒤집힌다

슬러지를 투입... 발효조 뚜껑을 닫고 에어락을 설치하고 작업완료~

비가와서 온도가 내려가면 발효에 딱 좋으련만.....


[인디아 페일 에일, IPA (India Pale Ale)]
페일 에일이 변형 발전된 형태의 맥주이다.
인디아 페일에일에 대해서 알아보려면 우선 이 페일에일에 대해서 알아야한다
19세기 산업화가 되면서 전통에일 맥주를 과학기술을 통해 대량생산이가능해졌고 그렇게 상업화된 맥주로써 페일 에일이라는 맥주가 탄생하였다
최초의 투명한 형태와 풍성한 탄산거품을 가진 맥주로 때문에 유리잔에 담에 먹게되었던 맥주이다
대영제국이 인도를 지배하게되면서 인도에 있는 영국인들의 요구에 의해 인도에서도 맥주가 필요해졌으나 인도의 더운 기온은 맥주를 담기 힘들며 영국에서 장기간 해상운송으로 맥주를 가져가게되면 맥주가 부패하는등의 문제가 발생되었다
이런 필요성에 의해서 기존 페일에일에서 알콜의 도수를 높이고 부패방지의 효과가 있는 홉[각주:1]의 사용량을 늘린 맥주가 만들어졌으며 이를 인디아페일에일 이라고 한다


[총 사용재료]
인디아 페일 에일 원액 1캔
스프레이몰트 라이트 500g X 2봉
Y1056 Wyeast American Ale 액상효모 3세대
말토덱스트린 100g

초기비중 : 1.050
종료비중 : 1.010
예상도수 : 5.24%
예상칼로리 : 173.4(12oz, 335ml 당)

병입시 설탕 500ml 당 5g

발효 시작일 : 2009/07/07 늦은 10시
병일일 : 2009/07/23
  1. 홉(hop) : 우리나라에서 흔히 맥주를 호프 라고 칭하기도 하는데그 "호프" 란 말의 기원이된것이 이 홉이다.마치 작은 솔방울과 비슷한 모양이며 맥주의 주 원료로써 사용되며 유럽에서는 진정,진통등의 민간요법으로도 이용된다빌헬름 4세의 맥주 순수령에서도 맥아, 물과 함께 포함된 3가지 기본요소 중 하나가 되는 전통적인 맥주의 필수재료이다이 홉은 특유의 향을 가지고 있어 맥주의 특성을 좌우할 수 있으며 맥주의 변질과 부패를 억제하는 역할 또한 가진다 [본문으로]
Posted by InuxKr
|


Posted by InuxKr
|

sqlplus 명령어

Oracle 2009. 4. 10. 23:47

1. 파일명령어

- SAVE :   SQLPLUS상에서 실행한 SQL문을 나중에 다시 사용하기 위해 운영체제 상의 디렉토리에 저장할 때 사용

  eg) save c:\scott_dept.sql

- START :  SAVE 명령어로 저장한 SQL 스크립트 파일을 SQLPLUS에서 직접 실행할 때 사용

 eg) start c:\scott_dept.sql

- GET :  SAVE로 저장한 SQL 스크립트 파일을 SQLPLUS 화면버퍼로 가져오는 명령

 eg) get c:\scott_dept.sql

- SPOOL :  SQLPLUS에서 실행하는 모든 SQL문과 결과를 지정된 디렉토리와 파일에 저장하는 명령

 eg) SPOOL c:\spool_examp.txt

- SPOOL off :  SPOOL 명령어들 종료하는 명령어

 eg) spool off

2. 편집명령어

- i : 이미 실행된 SQL문의 다음라인에 새로운 문법을 추가할 때 사용

- L :  이미 실행된 SQL문의 내용을 조회할 때 사용

- N :  숫자 값은 이미 작성된 SQL문의 해당 라인 내용을 보여줌

- C :  해당라인의 특정 내용을 다른 내용으로 변경

- DEL n :  지정한 라인을 완전히 삭제

- CLEAR BUFFER :  이미 작성된 모든 SQL문을 버퍼 영영그으로부터 완전히 삭제

3. 실행명령어

- START : 운영체제 상의 SQL스크립트를 실행하는 명령

- @ : START와 동일한 기능

- RUN : GET으로 SQLPLUS에 로드된 SQL문을 실행

- / : RUN관 동일한 기능

4. 환경 명령어

- SET FEEDBACK ON : SQL문이 실행된 후 작업처리 메시지를 출력

- SET FEEDBACK OFF : 메시지 출력을 해제(다량의 insert 문을 포함한 .sql 파일 실행에 좋음)

- SET HEADING OFF : 결과 출력시 칼럼명을 화면에 표지하지 않는 명령어

- SET HEADING ON : 칼럼명을 화면에 출력

5. 형식명령어

- COLUMN : 칼럼의 포맷을 변경

- TITLE : 보고서의 제몰을 설정

- BTITLE : 보고서의 꼬리말을 설정

- BREAK : 컬렴 또는 행의 값이 바뀔 때 마다 새로운 보고서 포맷을 설정할때

Posted by InuxKr
|

[펌] JSTL 기초

Development 2009. 1. 21. 10:22

개요

JSTL(JSP Standard Tag Library) 설명한다.

목차

1.      개요.. 3

2.      설정.. 3

3.      JSTL 사용.. 4

4.      Expression Language. 5

(1)    Expression Language 개요.. 5

(2)    Expression Language 기본 객체.. 6

(3)    객체 사용.. 6

(4)    연산자.. 9

5.      core. 10

(1)    c:out 10

(2)    c:set 11

(3)    c:remove. 11

(4)    c:if 11

(5)    c:choose, c:when, c:otherwise. 12

(6)    c:forEach. 12

(7)    c:forTokens 14

(8)    c:url, c:param. 14

(9)    c:import 15

(10)  c:redirect 16

(11)  c:catch. 16

6.      참고 자료.. 16



Posted by InuxKr
|

Posted by InuxKr
|
iBatis - mssql 연동시 Can't start a cloned connection while in manual transaction mode  에러가 나올경우

jdbc:sqlserver://{IP}:PORT;SelectMethod=cursor;DatabaseName={DBName} 처럼
 SelectMethod=cursor 을 추가해주면 된다
Posted by InuxKr
|