[java] MyBatis에서 빈번한 쿼리 최적화하기

소개

MyBatis는 자바 기반의 개발 프레임워크로써, 데이터베이스와의 상호 작용을 위한 SQL 매핑을 간편하게 만들어줍니다. 하지만 대량의 데이터를 처리하거나 빈번한 쿼리를 실행할 때 성능 이슈가 발생할 수 있습니다. 이러한 경우, MyBatis에서 제공하는 몇 가지 기능을 사용하여 쿼리를 최적화할 수 있습니다.

1. 벌크 연산을 사용하기

벌크 연산은 여러 개의 레코드를 한 번의 쿼리로 처리하는 기능입니다. 이를 통해 여러 개의 INSERT, UPDATE 또는 DELETE 문을 각각 실행하는 대신 단일 쿼리로 처리할 수 있습니다. 이는 빈번한 쿼리 실행 시간을 크게 단축시키는 데 도움이 됩니다.

아래 예제는 MyBatis의 벌크 연산을 사용하는 방법을 보여줍니다.

List<SomeData> dataList = ...; // 처리할 데이터 리스트

try (SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH)) {
    for (SomeData data : dataList) {
        sqlSession.insert("insertData", data); // INSERT 문 실행
    }
    sqlSession.commit(); // 벌크 연산 실행
} catch (Exception e) {
    sqlSession.rollback(); // 롤백
}

2. 캐시 사용하기

MyBatis는 이미 캐시 기능을 제공하고 있으며, 이를 이용하여 빈번한 쿼리 실행 결과를 캐시할 수 있습니다. 이를 통해 재실행 시 쿼리를 실행하는 비용을 줄이고 성능을 향상시킬 수 있습니다.

아래 예제는 MyBatis의 캐시 사용을 설정하는 방법을 보여줍니다.

먼저, MyBatis 설정 파일 (mybatis-config.xml)에서 캐시 관련 설정을 추가합니다.

<configuration>
    <!-- ... 기타 설정 ... -->
    
    <settings>
        <setting name="cacheEnabled" value="true" /> <!-- 캐시 활성화 -->
        <setting name="lazyLoadingEnabled" value="true" /> <!-- 지연 로딩 사용 -->
        <setting name="aggressiveLazyLoading" value="false" /> <!-- 미리 로딩된 컬렉션에 대한 지연 로딩 비활성화 -->
        <setting name="defaultStatementTimeout" value="25000" /> <!-- 기본 쿼리 실행 제한 시간 설정 -->
    </settings>
    
    <!-- ... 기타 설정 ... -->
</configuration>

그리고 매퍼 파일에서 해당 쿼리에 대한 캐시 속성을 설정합니다.

<!-- ... 매퍼 파일 내용 ... -->

<select id="getData" resultType="SomeData" flushCache="false" useCache="true">
    <!-- 캐시 사용 설정 -->
    SELECT * FROM data_table WHERE id = #{id}
</select>

<!-- ... 매퍼 파일 내용 ... -->

3. 쿼리 로깅하기

쿼리 실행 시간을 확인하고 성능 향상을 위해 쿼리 로그를 남길 수 있습니다. 이를 통해 어떤 쿼리가 가장 오래 걸리는지 식별하고, 쿼리 최적화에 도움이 되는 정보를 확인할 수 있습니다.

아래 예제는 MyBatis에서 쿼리 로그를 남기는 방법을 보여줍니다.

먼저, MyBatis 설정 파일 (mybatis-config.xml)에서 로깅 관련 설정을 추가합니다.

<configuration>
    <!-- ... 기타 설정 ... -->
    
    <settings>
        <!-- ... 기타 설정 ... -->
        <setting name="logImpl" value="STDOUT_LOGGING" /> <!-- 로그 출력 방식 설정 -->
    </settings>
    
    <!-- ... 기타 설정 ... -->
</configuration>

그리고 해당 로깅 설정을 위해 log4j.properties 또는 logback.xml 파일을 프로젝트에 추가합니다.

log4j.properties:

log4j.rootLogger=DEBUG, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n

logback.xml:

<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss} %-5p %c:%L - %m%n</pattern>
        </encoder>
    </appender>

    <root level="info">
        <appender-ref ref="STDOUT"/>
    </root>
</configuration>

결론

MyBatis에서 빈번한 쿼리 최적화를 위해 벌크 연산, 캐시 사용, 쿼리 로깅 등의 기능을 활용할 수 있습니다. 이러한 기능을 적절히 활용하여 성능 개선을 도모해야 합니다. 그러나 모든 상황에 맞는 최적화 기법을 선택하고 구현하는 것이 중요합니다.

참고문헌: