Database/Cassandra

[Cassandra][java] PreparedStatement vs Statement

bisi 2020. 5. 20. 10:11

PreparedStatement, Staement 개념

PreparedStatement와 Statement의 가장 큰 차이점은 캐시(cache) 사용여부이다. 

 

주요 역할

① 쿼리 문장 분석

② 컴파일

③ 실행 

 

Statement를 사용하면 매번 쿼리할때마다 3가지 주요역할을 수행한다.

하지만 PreparedStatement는 처음 한번만 3가지 주요역할을 수행하고, 캐시에 담아 재사용한다.

 

 

특징 비교 

Statement  PreparedStatement 
어떤 SQL문을 사용하는지 파악하기 쉽다.
executeQuery() 나 executeUpdate() 를 실행하는 시점에 파라미터로 SQL문을 전달
어떤 SQL문을 사용하는지 파악하기 어렵다. 
보통 조건절과 함께 사용되며 재사용이 되는데, ? 부분에만 변화를 주어 지속적으로 SQL을 수행하기 때문
매번 쿼리를 할때마다 컴파일을 하기 때문에 성능상의 이슈가 있을 가능성이 있다. 미리 Statement를 컴파일 실행하기 때문에 성능상 이점이 있다.
정적 SQL 문을 실행해, 작성된 결과를 돌려주기 위한 오브젝트이다. 디폴트에서는 Statement 오브젝트 마다 1개의 ResultSet 오브젝트 만이 동시에 오픈할 수 있다.
Statement를 상속 받음.
SQL문은 프리 컴파일 되어 PreparedStatement 오브젝트에 저장된다. 이 오브젝트는 이 문장을 여러 차례 효율적으로 목적으로 사용할 수 있다. 

 

만약 동일한 쿼리를 계속 실행하는 것이라면 PreparedStatement 사용하는 것이 DB에 훨씬 적은 부하를 주며, 성능도 좋다. 하지만 Dynamic SQL을 사용할 경우에는 반드시 Statement를 사용해야 한다. 

 

카산드라 데이터 베이스 기반의 SQL문 실행시, 예제 코드 

1) PreparedStatement

public static void main(String[] args) {

		Session session = Connection.connect();		
		PreparedStatement preparedStatement = session.prepare("insert into user (id, name, age) values (?, ?, ?)");

		try {
			BoundStatement boundStatement = preparedStatement.bind(UUIDs.timeBased(), "Hector", 34);
			ResultSet rs = session.execute(boundStatement);
			System.out.println(rs);
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		
		Connection.close();

	}

Programcreeke 참고

 

 

2) Statement

public void insertBookBatch(Book book) {
    StringBuilder sb = new StringBuilder("BEGIN BATCH ")
      .append("INSERT INTO ").append(TABLE_NAME)
      .append("(id, title, subject) ")
      .append("VALUES (").append(book.getId()).append(", '")
      .append(book.getTitle()).append("', '")
      .append(book.getSubject()).append("');")
      .append("INSERT INTO ")
      .append(TABLE_NAME_BY_TITLE).append("(id, title) ")
      .append("VALUES (").append(book.getId()).append(", '")
      .append(book.getTitle()).append("');")
      .append("APPLY BATCH;");
 
    String query = sb.toString();
    session.execute(query);
}

Bealdung : A Guide to Cassandra with Java 참고

 

 

PreparedStatement는 모든 Database에서 성능이 좋을까?

이론상으로는 PreparedStatement의 성능이 statement 보다 빠르지만, DB 서버에 따라 성능 차이가 나지 않을 수 있다.

 

카산드라와 테스트 환경에서 적용해보면 response time이 눈에 띄게 개선되는 것 같진 않아 보인다고 한다.

각자의 환경에 맞게 구성 후, 사전에 response time 성능 테스트가 필요해보인다.

Next, we fill the table with some realistic time series sensor data. You can change how many host names (100 by default) are used, and how many timestamps are generated. For each time 3 metrics and values will be inserted. There are several types of statements in the Java clients including simple and prepared statements. In theory prepared statements are faster so there’s an option to use either in the code. In practice it seems that prepared statements may not improve response time significantly but may be designed to improve throughput.  Realistic looking data is generated by a simple random walk.

레퍼런스 바로가기

 

또한 오라클 DB에서는 DB 서버에서 미리 준비된 SQL을 사용하게 되고 파싱과정을 생략하기 때문에 DB 리소스를 효율적으로 사용하도록 한다. 하지만 MySQL 과 같은 경우엔 성능이 거의 차이가 나지 않는다.

 

요약하자면 PreparedStatement의 성능은 DB서버에 따라 다르므로 사전에 성능테스트가 확인이 필요해보인다. 

 

 

참고 

https://docs.datastax.com/en/drivers/java/2.0/com/datastax/driver/core/Statement.html

https://docs.datastax.com/en/developer/java-driver/3.0/manual/statements/prepared/

https://www.instaclustr.com/hello-cassandra-java-client-example/

https://www.baeldung.com/cassandra-with-java

https://devbox.tistory.com/entry/Comporison