50129


現在、APIから情報を取得し、MySQLデータベースに保存するプログラムを書いています。ベースはpythonで、使用するドライバはmysql-
connector-pythonです。

実行環境  
・DB: MySQL8.0  
・ドライバ: mysql-connector-python  
・対象API: 仮想通貨取引所の価格データ

そこで、DBとのコネクションの確立とクローズのタイミングについて疑問があります。

今回のAPIからデータを保存する流れでは、データ量が多いため、APIでデータ呼び出し->データ保存のサイクルを何度も回す流れになります。このとき、DBとのコネクションを確立させたままにして、APIからデータ取得->保存を繰り返すのが良いのか、または一回保存する度にコネクションの確立とクローズも一緒に行うのか、悩んでいます。  
上記を整理した図は以下になります。

  1. DBとのコネクション確立-> [API呼び出し->DBにデータ保存]を繰り返し ・・・コネクションは確立しっぱなし
  2. [DBとのコネクション確立->API呼び出し->DBにデータ保存->DBとのコネクションクローズ]を繰り返し

ググってみた限りでは、コネクションの確立とクローズは負荷が大きいので接続しっぱなしが良いという意見と、都度コネクションの確立とクローズをするのが一般的との2つの意見が出てきました。

ただ、それ以上の判断軸が判然としなかったので、こちらで質問させて頂きました。


CC BY-SA 4.0
2018-11-09T10:22:56.963
50124
2018-11-10T07:35:47.853
2018-11-09T11:54:56.583
3060
29884
question
mysql
MySQL DBとのコネクションの確立とクローズのタイミングについて


通常、DBサーバーとのアクセスが多いアプリケーションは、性能を考慮してコネクションプール（②の方式）を使用します。

コネクション確立からクローズまでのそれぞれの過程にかかる時間を以下とし、

  * DBとのコネクション確立：t1
  * API呼び出し：t2
  * DBにデータ保存：t3
  * DBとのコネクションクローズ：t4

繰り返しの回数をnとすると、①と②の応答時間は次のようになります。

  * ①： (t1 + t2 + t3 + t4) * n
  * ②： t1 + (t2 + t3) * n + t4

両者の差は(t1 + t4) * (n -
1)なので、繰り返し回数nが大きくなるほど、この差が無視できなくなります。1つのコネクションの生成に約0.1秒かかってたとしても、それを10,000万回くらい返したら、約1,000秒=17分近く余分にかかります。Webアプリケーションの場合は、nが１０程度でも応答時間が１秒遅れることになるので、問題になります。また、コネクションの確立とクローズは、応答時間以外にもCPU使用量などにも影響を与えます。

それでも性能要件として問題なければ、①の方が単純でいいかもしれませんが、一般的には②を使用した方が無難です。コネクションプーリングを使用するデメリットをあえて挙げると、コネクションプーリング特有の問題が発生することでしょうか。例えば、ファイアウォールが無通信のコネクションを切断することで、不良コネクションがプールに溜まってしまうような問題が起きる場合があります。

ちなみに、コネクションプールの実装は単純ではないので、自分でつくろうとはせず、既存のものを使いましょう。MySQL
Connector/Pythonだと[このページ](https://dev.mysql.com/doc/connector-
python/en/connector-python-connection-pooling.html)でしょうか。

コネクションプーリングに関する説明は、以下のページが詳しく、分かりやすいと思います。

[門外不出のOracle現場ワザ - 第5章 DBアクセスの空白地帯
コネクションプーリングを極める](https://www.oracle.com/technetwork/jp/articles/chapter5-1-101584-ja.html)


CC BY-SA 4.0
2018-11-09T12:13:29.200
50129
2018-11-09T12:22:26.147
2018-11-09T12:22:26.147
21092
21092
50124
answer


開発しているプログラムがどのようなものか、どんな使われ方をするものか、といったところで判断材料は変わってくるかと思います。

サーバサイドプログラムでしたら、同時に使用するのが普通ですから、パフォーマンスを優先して、コネクションを使いまわしたほうがいいでしょう。

ユーザーアプリケーションでしたら、どの程度の頻度で、API実行、DBアクセスを繰り返すか で性能の影響は異なって来ると思います。たとえば、1秒間に何回
APIを実行するか（≒DBに書き込むか）を基準にして 考えてみてはどうでしょう。そうすると、1回あたりの API実行～DB書き込み までに
必要な処理時間がわかります。サンプルプログラムなどでその目標の性能が出せるか 検証することができます。


CC BY-SA 4.0
2018-11-10T07:35:47.853
50159
2018-11-10T07:35:47.853
5008
50124
answer