前回に続いてmysql-nativeネタ。 FAQみたいなのに残しておいたほうが説明とかする時に楽そうなので。 その1と書いたがその2があるとは言ってない(?)
Q1: 都度コネクションをクローズするのは効率的にどうなのか?
ウェブアプリケーション内で以下のようなコードでレスポンスする際にcloseするようにすると効率がよくないのではないか?
auto conn = pool.lockConnection; scope(exit) conn.close;
A1: コネクションプールを使う場合はcloseを明示的に使わず任せてしまおう
心配のようにcloseは実際に接続を閉じる。都度接続の場合はそうすべきだがコネクションプールを使う場合は毎回クローズするよりもmaxConcurrencyの値を適切なものにして明示的に呼ばないほうがよい。
Q2: コネクションプールはどこに配置するのがよいか?
たとえばTLSにおいてワーカースレッド毎に別々のプールを使うのがよいのか、
MySQLPool pool; static this() { pool = new MySQLPool(...); }
グローバルにおいて排他制御するのか
__gshared MySQLPool pool; shared static this() { pool = new MySQLPool(...); }
どういった形でコネクションプールを配置すればいいのかよくわからない。
A2: 上の例でいえばTLSごとに持つべき(スレッド間で共有できないため)
そもそも基盤となっているモジュールvibe.core.connectionpool
は別スレッドからのコネクション取得に対応していないため後者のようなことはできない。消去法でTLSで保持する選択肢に自ずと決まってくる。
Q3: ドライバがいくつかの機能をサポートしていないことによる不利はあるか?
(MySQL8前提として)現時点だと最適化のためのいくつかの機能が欠損している:
それ以外の機能としてもいくつか未サポートのものがある:
こうした機能をサポートしていないことによって他の言語と比べて性能上不利になるようなことはあるか?
A3: 多少不利になる要素はあるが、決定的な要因とはならないだろう
たしかに他の言語のドライバと比較して未サポート機能が多いために不利になることはあるかもしれないが、上にあげた機能によるものが決定的な要因となることは考えにくい。 それよりもクエリのチューニングであるとか通信回数を減らす工夫のほうが支配的な要因となるため、それほど深刻に考える必要はないと思われる。