설문조사
PostgreSQL/PPAS 관련 듣고 싶은 교육은


총 게시물 162건, 최근 0 건
   

개발 언어별 prepared statement 특성 다섯번째팁

글쓴이 : ioseph 날짜 : 2014-11-18 (화) 02:38 조회 : 6863
python이나, php 에서는 이 api를 사용하면 바로 서버측에서 해당 쿼리의 실행계획까지 짜여진 정보가 저장 되지만, 
java jdbc에서는 그렇지 않습니다. 
많은 java 개발자들이 이 부분을 놓치고 있답니다. 

무조건 서버측 prepared statement 기능을 사용하려면, 
jdbc connection url에서 query string값으로 prepareThreshold=1 로 지정해 주어야 합니다. 

jdbc:postgresql://host:port/database?prepareThreshold=1 

형태가 되겠지요. 
db pool을 사용하고, 쿼리 패턴이 일정하다면, 이 설정이 꽤 도움이 될듯합니다. 특히나 게임서버나, 기타 미들웨어 서버를 만드는 경우에.


처음부터 2014-12-17 (수) 10:15
Server측 Prepared Statement는 여러 제한 조건이 있습니다.
1. 동일 Session에서만  가능
2. 해당 session이 끝나면 메모리에서 deallocate됨
3. PREPARE로 서버측 prepared statement 선언할 때의 명칭과 Query과 동일하여야 함 등.

문제는, JDBC Driver 구현을 살펴보면, 우리가 익히 사용하고 있는 Prepared Statement는 익명(Anonumous)PreparedStatement라. 해당 Prepared Statement 를 사용하고 해당 Instance를 버리면 새로운 이름이 추가된다는 점입니다. 이로 인행서, prepareThreshold 값이 의미가 없어집니다.

실질적으로 PreparedStatement 를 유용하게 사용하려면 다음과 같은 전제 조건을 만족해야 합니다.
(in JDBC)
1. 특정 PreparedStatement를 사용하는 Session은 특정 Session에 한정지어야 한다.
  모든 Query가 개별 Session에 모두 PREPARE로 메모리 할당을 하려고 하면
  동일 Query가 Session수 만큼 메모리에 할당받으려고 하기 때문에 메모리가 많지 않다고 기존
  PreparedStatement를 제거하고, 다시 할당받아 도리어 성능을 잡습니다.
2. PreparedStatement Instance 자체를 재사용해야 한다.
  즉 개별 API/Method별로,
  PreparedStatement stmt = ... ();
  ...
  stmt.close();
  이렇게 하면, 말짱 도루묵이 됩니다. 실제로 사용하고 싶다면

  static PreparedStatement stmt_for_case1 = null;
  static { initializePreparedStatement(); }

  그다음에는

  stmt_for_case1.setString(1,"aaa");
  ...
  stmt_for_case1.executeQuery();

  이렇게 활용해야, Server측 Prepared Statement가 진행됩니다.
3. 위에서 설명한 prepareThreshold 값을 1로 Setting하면, 한번 실행한 이후,
    해당 Query가 메모리에 적재됩니다

위 내용을 모두 반영하는 Java측 Framework이 있다면 공유 부탁드립니다.
현재까지 찾아보고 있지만 없는 것 같습니다.

현재 PostgreSQL에서 사용하는 PreparedStatement의 용도는 SQL Injection에 대한 대비책과
함께, CUD Multi Row 처리에는 효과가 큰 것 같습니다.

  PreparesStatement stmt = ...
  for ( Record rec : records ) {
    ...
    stmt.executQuery():
  }

이런식의 반복문 안에서는 매우 유용합니다.
댓글주소
PostgresDBA 2015-03-27 (금) 15:35
참고로, 명시적으로 지정하지 않았을 경우 자바에서 prepareThreshold 의 디폴트값은 5 입니다.
댓글주소
   

postgresdba.com