明確にするために-Node.jsはそうではありません シングルスレッド。アプリケーションコードは1つのスレッドで実行されますが、内部では必要に応じて使用されます。ここ (回答とその下のコメントの両方):
そして:
ご覧のとおり、mysql
使用するモジュールでは、query()
のコールバックを渡す必要があります メソッド(そしておそらくもっとたくさん)。したがって、これを呼び出すと、コードの実行が続行され、データベースからの結果が到着したときにコールバックが呼び出されます。
あなたの質問に関しては-あなたはすべての要求に対して新しい接続を作成しているわけではありません。 readmeをご覧ください mysql
のファイル モジュール、プール接続 セクション
:
dbPool.getConnection()
を呼び出すとき 接続は、プールに使用可能な接続がなくなった場合にのみ作成されます。それ以外の場合は、プールの上部から接続を取得するだけです。 objConn.release()
を呼び出す 接続を解放してプールに戻します-切断されていません。この呼び出しにより、アプリケーションの他の部分で再利用できます。
要約すると:
- リクエストごとに新しい接続を作成することはお勧めできません アプリとデータベースの両方のマシンでより多くのリソース(CPU、RAM)を使用するためです。
- すべてのリクエストに1つの接続を使用することも間違っています。これは、いずれかの操作の完了に時間がかかると、接続がハングし、他のすべてのリクエストがそれを待機するためです。
- 接続プールの使用 は、データベースの1つが完了するまでに長い時間がかかる場合でも、データベースに対して同時に複数の操作を実行できる優れたアイデアです。
更新: コメントからの質問に答えるには:
リクエストごとに1つの接続を使用している場合、mysql
モジュールは、クエリを実行する前に、新しいソケットを開き、データベースに接続して認証する必要があります。これには時間がかかり、リソースを消費します。そのため、それは悪いアプローチです。
一方、接続を1つだけ使用する場合 (接続プールではなく)、完了するのに長い時間がかかるクエリを実行すると、完了するまでその接続で他のクエリがブロックされます。つまり、他のリクエストは待機する必要があります。これも悪いアプローチです。
pool.getConnection()
を呼び出さない限り、リクエストごとに新しい接続プールを作成することは、新しい接続を使用することとほとんど同じです。 複数回-その後はさらに悪化します(新しい接続を作成するために使用されるリソースを取得し、それをpool.getConnection()
の数で乗算します 呼び出し)。
操作ごとに1つの接続をさらに明確にするため vs1つの接続でのすべての操作 質問:
すべての接続の各操作は、前の操作が完了した後に開始されます(同期ですが、クライアント側ではありません)。したがって、数十億行のテーブルがあり、SELECT * FROM yourtable
を発行する場合 完了するまでに時間がかかり、この接続のすべての操作が完了するまでブロックされます。
並行して発行する必要のある操作ごとに(たとえば、要求ごとに)1つの接続がある場合、問題は解消されます。ただし、前述のように、新しい接続を開くには時間とリソースが必要です。そのため、接続プール コンセプトが導入されました。
したがって、答えは次のとおりです。すべてのリクエストに1つの接続プールを使用する (サンプルコードの場合と同様)-接続数は、アプリのトラフィックに応じて増加します。
更新#2:
コメントに基づいて、接続プールの背後にある概念についても説明する必要があることがわかりました。仕組みは、接続プールを空にして初期化し、最大 nを作成してアプリを起動することです。 接続(mysql
の場合は10です デフォルトではモジュール)。
dbPool.getConnection()
を呼び出すときはいつでも プールに利用可能な接続があるかどうかをチェックします。ある場合はそれを取得し(使用できなくなります)、ない場合は新しいものを作成します。接続制限に達し、使用可能な接続がない場合、なんらかの例外が発生します。
connection.release()
を呼び出す 接続を解放してプールに戻し、再び利用できるようにします。
プールを使用してアプリ全体で1つのグローバル接続のみを取得することは完全に間違っており、概念自体に反します(接続を手動で作成するだけで同じことができます)。したがって、接続プールを使用する つまり、使用されるはずの接続プールを使用します-必要なときに接続プールから接続を取得します 。