グローバルナビゲーションへ

本文へ

フッターへ

お役立ち情報Blog



database/sqlのrowsのメモリ量を調査する

今回はGoの「database/sql」を使って、結果が大きいクエリを発行したときにヒープのメモリ量を見ていきたいと思います。

検証理由

多くの場合LimitとOffsetを指定するのですが、大量の結果が返されるときに rows がどのくらいメモリを使っているのか知りたくなりました。

 rows.Next  rows.Scan を利用するので、 rows に結果が一度に入りヒープのメモリ量が増えることはないだろうという前提での検証です。

準備

MySqlにUUIDが入っているカラムと、テキトウな文字を入れるカラムを用意して、そこに30,000件のデータを登録しておきます。

内容はこんな感じになります。

次に、検証用のコードを書きます。
今回は、簡単にヒープに割り当てられたメモリ量を表示しています。

実際に動かしてメモリを計測する

それでは、sql部分にLimitを追加して検証していきたいと思います。

左から、ヒープに割り当てられたメモリ量、ヒープに割り当てられたメモリの総量(減らない)、OSから取得したメモリ量です。

Limit: 10
376048 376048 71650320
376256 376256 71912464
376544 376544 71650320

Limit: 10000
1202960 4504840 73679880
1235760 4505128 73942024
1134624 4504952 73483272

Limit: 20000
1510472 8630744 74007560
1460512 8629504 74269704
1462568 8632184 74269704

Limit: 30000
1823432 12766528 74269704
1945400 12764736 74269704
1959984 12764528 74269704

Limitを上げると順調にヒープが育っていってます。

次に、上記コードのGC部分のコメントを外して実行します。(検証用にGCをコールしています)

Limit: 10
223784 382464 71715600
226216 384672 72239888
226264 385360 72239888

Limit: 10000
224800 4503592 74269704
224472 4504720 74269704
226152 4504200 74269704

Limit: 20000
226848 8632624 74269704
229000 8633136 74007560
224312 8628920 74007560

Limit: 30000
228488 12765656 74269704
226488 12764600 74269704
224776 12764296 74007560

今度はGCによって削除されているのがわかります。

次に、ループ中のメモリを調べたいので、少し強引ですが rows.Next のループ毎にGCを呼んでみます。
毎回GCを呼ぶのでかなり遅くなることが予想されます。

Limit: 10
228624 399640 74007560
228640 401680 74007560
228632 403752 74007560

Limit: 10000
250304 22738464 74269704
250304 22741000 74269704
250400 22743632 74269704

Limit: 20000
251448 45285408 74335240
251448 45287880 74335240
251448 45290352 74335240

Limit: 30000
253800 67179272 74269704
253800 67181200 74269704
253800 67183336 74269704

手元の環境だと30000レコードで9秒かかりました。

こちらもヒープのメモリ量は一定になりましたが、GCが多発すると遅くなることが実感できます。

まとめ

簡易的な検証でしたが、以下のような予想ができます。

  • 一度に大量の行をクエリすると、database/sqlのrowsのヒープは増えていく
  • GCが実行されると削除されるが、GCが過剰に実行されると遅くなる
The following two tabs change content below.

tkr2f

事業開発部 web application engineer
2008年にアーティスへ入社。 システムエンジニアとして、SI案件のシステム開発に携わる。 その後、事業開発部の立ち上げから自社サービスの開発、保守をメインに従事。 ドメイン駆動設計(DDD)を中心にドメインを重視しながら、保守可能なソフトウェア開発を探求している。
この記事のカテゴリ

FOLLOW US

最新の情報をお届けします