概要
EmbulkでMySQLからデータを抽出しようとしたら遅かったので、関連となるトピックを色々調べた。とりあえず参考リンクだけ貼っておく。
クエリ処理の流れ
(SQL Server) SELECT ステートメントを処理する
<非公式> MySQL Logical Architecture
プリペアドステートメント
サーバサイドエンジニアなら分かっておきたいPrepared文についての要点
プリペアドステートメントと結果セット
Fetch size
大きな結果セット用のメモリーが足りないことで問題が発生する場合は、--quick オプションを使用します。 これにより mysql は、全結果セットを表示前に取得してメモリー内でバッファリングする代わりに、サーバーから 1 行ずつ結果を取得することを強制されます。
- fetch_rows: number of rows to fetch one time (integer, default: 10000)
- If this value is set to > 1:
- It uses a server-side prepared statement and fetches rows by chunks.
- If this value is set to 1:
- It uses a client-side built statement and fetches rows one by one.
- Internally,
useCursorFetch=false
is used andjava.sql.Statement.setFetchSize
is set to Integer.MIN_VALUE.- If this value is set to -1:
- It uses a client-side built statement and fetches all rows at once. This may cause OutOfMemoryError.
- Internally,
useCursorFetch=false
is used andjava.sql.Statement.setFetchSize
is not set.
速度改善
https://www.manageengine.jp/products/Applications_Manager/solution_mysql-speed-improvement.html
https://airbyte.com/data-engineering-resources/optimizing-mysql-queries
ページネーション
ページネーション vs カーソル
Offset vs Cursor-Based Pagination: Which is the Right Choice for Your Project?
Offset pagination vs Cursor pagination
ResultSetとJVMメモリ
Does jdbc dataset store all rows in jvm memory
ResultSet behavior with MySQL database, does it store all rows in memory?
JVM ヒープ領域
JVMヒープとコンテナ
コンテナではカーネルの CGroup という機能を使って、コンテナ内のプロセスが利用できるメモリを制限できます。 しかしコンテナ上でメモリサイズを取得しても、見えるのはコンテナホスト側のメモリサイズです。 コンテナ内でfreeコマンドを打つと、なぜかホスト側のメモリサイズが表示されるといった経験をしたことがある人もいるでしょう。 この問題を解決するために、メモリサイズではなく CGroup からヒープサイズを取得するオプションが Java 9 から追加されました。
UseContainerSupport は Java 10 に追加されたオプションです(JDK-8146115)。 また Java 8u191 などにもバックポートされました。 UseContainerSupport は CGroup からメモリ制限を取得するだけでなく、次の機能もあります。
- CGroup の CPU の制限値も使用する
- CGropu 上のメモリの利用率も取得できる
UseContainerSupport オプションはデフォルトで有効になっています。 そのため特に何も指定しなくても、コンテナが利用できるメモリ容量の 1/4 がヒープサイズとして割り当てられます。