はじめに (対象読者・この記事でわかること)

この記事は、JavaとMyBatisを使用したWebアプリケーション開発を担当している方、特に大量データの取得パフォーマンス改善に悩んでいる方を対象としています。

この記事を読むことで、MyBatisでfetchSizeが効かない問題の原因を理解し、適切な設定方法を学ぶことができます。具体的には、データベース接続プールとの関係性や、MyBatisの設定方法、JDBCの仕組みに関する知識を深め、実際のアプリケーションでfetchSizeを正しく適用するための具体的な手順がわかります。

多くの開発者が遭遇するこの問題を解決し、アプリケーションのパフォーマンスを向上させるための実践的な知識を提供します。

前提知識

この記事を読み進める上で、以下の知識があるとスムーズです。

  • Javaの基本的な知識
  • MyBatisの基本的な使い方
  • SQLとデータベースの基本知識
  • MavenやGradleのビルドツールの基本的な知識

MyBatisのfetchSizeとは

MyBatisのfetchSizeは、JDBCのStatementオブジェクトに設定されるFetch Sizeのことで、データベースから一度に取得する行数を制御するパラメータです。大量のデータを扱う際に、fetchSizeを適切に設定することで、メモリ使用量を抑えつつパフォーマンスを向上させることができます。

しかし、実際の開発現場ではMyBatisで設定したfetchSizeが期待通りに機能せず、全件取得されてしまうという問題が発生することがあります。この問題は、単なる設定ミスではなく、MyBatisの動作原理やデータベース接続プールとの関係性を理解しないと解決が難しい場合があります。

fetchSizeが効かない原因と解決策

原因1:データベースドライバの対応状況

まず確認すべきは、使用しているデータベースドライバがfetchSizeに対応しているかどうかです。一部のドライバではfetchSizeの設定が無視される場合があります。

解決策: 使用しているデータベースドライバがfetchSizeに対応しているか確認し、対応していない場合は別のドライバへの乗り換えを検討します。例えば、MySQLの場合は最新のConnector/Jを使用することでfetchSizeが正しく機能します。

原因2:データベース接続プールの設定問題

データベース接続プール(例:HikariCP、DBCPなど)によっては、fetchSizeの設定が上書きされてしまう場合があります。特に、接続プールが内部でStatementオブジェクトをキャッシュしている場合、設定したfetchSizeが保持されません。

解決策: データベース接続プールの設定を確認し、fetchSizeが保持されるように設定します。HikariCPを使用している場合は、以下のように設定します。

Properties
# HikariCPの設定例 spring.datasource.hikari.connection-init-sql=SET default_fetch_size=100

また、接続プールの実装によっては、以下のように接続URLにパラメータを追加する必要があります。

Properties
# MySQLの場合 spring.datasource.url=jdbc:mysql://localhost:3306/mydb?useServerPrepStmts=true&useServerPrepStmts=true&rewriteBatchedStatements=true&cachePrepStmts=true&useLocalSessionState=true&rewriteBatchedStatements=true&cacheResultSetMetadata=true&cacheServerConfiguration=true&elideSetAutoCommits=true&maintainTimeStats=false&useServerPrepStmts=true&useLocalSessionState=true&rewriteBatchedStatements=true&cacheResultSetMetadata=true&cacheServerConfiguration=true&elideSetAutoCommits=true&maintainTimeStats=false&useServerPrepStmts=true&useLocalSessionState=true&rewriteBatchedStatements=true&cacheResultSetMetadata=true&cacheServerConfiguration=true&elideSetAutoCommits=true&maintainTimeStats=false&defaultFetchSize=100

原因3:MyBatisのマッパー設定不足

MyBatisでfetchSizeを有効にするには、マッパーXMLファイルまたはアノテーションで明示的に設定する必要があります。設定が不足している場合、fetchSizeは適用されません。

解決策: マッパーXMLファイルの