Statement와 Prepared Statement

1 minute read

Statement와 Prepared Statement

Q1. Statement와 Prepared Statement에 대해 설명해보시오.

보기

Java에서는 쿼리를 Statement 혹은 Prepared Statement라는 객체에 담아 DB에 전달하는데
Statement는 완성된 정적 쿼리가 DB로 전달되는 방식을 말하고
Prepared Statement는 쿼리를 미리 컴파일하고 사용될 파라미터와 함께 DB로 전달되는 방식을 말한다.


Q2. Prepared Statement가 Statment를 비교하여 설명해보시오. (성능, 장단점)

보기

Prepared Statement가 대부분의 경우에서 Statement보다 낫다.
DB는 쿼리 수행시 다음의 3단계를 거친다.

  1. 쿼리 분석
  2. 쿼리 컴파일
  3. 쿼리 수행

성능적인 측면
Prepared Statement는 미리 컴파일된 SQL문을 사용하기 때문에 "쿼리분석"과 "쿼리컴파일" 과정이 생략된다.
하지만 Statement는 매번 쿼리 분석과 컴파일 과정을 거치지 때문에 전체 수행 속도가 상대적으로 느리다.

또한 Prepared Statement는 자주 사용하는 쿼리에 대해 컴파일 결과를 주로 캐시해놓고 사용한다.
쿼리 자체는 동일하고 사용되는 파라미터만 변경되는 것이기 때문에 재사용률이 Statement보다 높다.

보안적인 측면
Prepare Statement는 쿼리는 동일하고 사용되는 파라미터만 변경되기 때문에 SQL Injection으로부터 안전하다.
반면에 Statement는 사용자 입력으로부터 쿼리가 생상되므로 Injection의 위험이 있다.

따라서 항상 Statement보다 Prepared Statement를 사용하는 습관을 들이는게 좋다.

요약

성능적인 면에서 미리 컴파일 되어 있기도 하고 캐시 사용률이 높아 Prepared Statement가 우수
보안적인 면에서 SQL Injection 위험으로부터 안전하기 때문에 Prepared Statement가 우수


Q3. 그렇다면 Prepared Statment를 쓰는 것 보다 Statement를 쓰는 것이 성능적으로 더 나은 상황은 없는가?

보기

쿼리 자체가 변하지 않는 경우, 즉 쿼리와 결과가 거의 동일한 경우에 대해서는 Statement가 낫다.

왜냐하면 Prepared Statement는 쿼리를 캐시하여 사용하는데
DB는 쿼리가 같고 자주 사용된다면 해당 결과까지 캐싱하여 제공한다.

DB 데이터 접근 과정을 거치지 않고 캐시에서 바로 데이터를 제공해주기 때문에 빠를 수 있다.


Q4. Prepared Statement를 사용할 수 없는 상황은 어떤 것들이 있을까?

보기

Dynamic SQL를 사용해야 하는 경우엔 Prepared Statement를 사용 할 수 없다.

예를 들면

  1. 어떤 조건에 따라 조회하는 칼럼이 달라진다던지
  2. 조건에 따라 쿼리 자체가 달라진다던지
  3. 조건에 따라 join하는 테이블이 달라진다던지 등등...

이렇게 Dynamic SQL을 사용해야 하는 경우에는 Prepared Statement를 사용할 수 없다.


참고
mybatis와 ibatis의 경우 내부적으로
#{value} 또는 #value#를 사용하면 prepared statement를 사용하고
${value} 또는 $value$를 사용하면 statement를 사용한다.