プログラマ38の日記

主にプログラムメモです。

JDBC: 接続URLではまったこと(SQLServer , MySQLでメモリエラーが発生する件)

Javaで、SQLServerMySQLのデータ連携プログラムを書くとき注意事項のメモです。(ある程度の件数がある時の場合です。)

 

結論としては jdbcのURLのパラメータをきちんと書かないと、「out of memory」のエラーになる可能性が高くなります。

 

「out of memory」エラーになる書き方

SQLServer
jdbc:sqlserver://[ホスト名]:[ポート番号];databaseName=[データベース名]

MySQL
jdbc:mysql://[ホスト名]:[ポート番号]/[データベース名]

 

「out of memory」エラーにならない書き方

SQLServer
jdbc:sqlserver://[ホスト名]:[ポート番号];databaseName=[データベース名];SELECTMETHOD=cursor

MySQL
jdbc:mysql://[ホスト名]:[ポート番号]/[データベース名]?useCursorFetch=true&defaultFetchSize=1000

 

SQLServerでは、selectmethod=cursor 、 MySQLではuseCursorFetch=trueでかつdefaultFetchSize=XXXを指定しないと取得結果がメモリに展開されてしまい、データがメモリの容量を超えるとエラーになります。

 

SQLServerは、selectmethod=cursorを設定しない場合、デフォルトでselectmethod=direct扱いとなり、一方的にDBから結果が送られてきます。DBからの結果を全てメモリに展開してから次の処理が動くわけではないのがまだましです。

ですが、MySQLでは、useCursorFetch=trueでかつdefaultFetchSize=XXXを指定しないと、全てメモリに展開してから次の処理が動きます。100万件程度を操作するとほぼメモリエラーになると思います。

 

最後に

JavaベースのETLツールもありますので、jdbc urlには充分注意が必要です。

jdbc urlでは、パラメータを指定しない場合は、遅いけどエラーにならない動きを選択して欲しいなと思いました。

 

MySQLである程度のデータを取得する場合、パラメータを指定しないとまずエラーというのはひどい設計だと思います。Oraclejdbcドライバではパラメータを指定しなくてもエラーにならないので安定してるなーと思います。