詳細は実装に依存しますが、一般的に 言えば、結果はバッファリングされます。データベースに対してクエリを実行すると、いくつかの結果セットが返されます。十分に小さい場合は、最初の呼び出しですべての結果が返される場合もあれば、結果オブジェクトを反復処理するとさらに多くの結果が返される場合もあります。
シーケンスを次のように考えてください:
- データベースへの接続を開きます;
- データベースを選択するための2回目の呼び出しがあるか、(1)の一部として実行される可能性があります。
- その認証と接続の手順は、(少なくとも)サーバーへの1回のラウンドトリップです(永続的な接続は無視されます)。
- クライアントでクエリを実行します。
- そのクエリはサーバーに送信されます;
- サーバーはクエリの実行方法を決定する必要があります;
- サーバーが以前にクエリを実行したことがある場合、実行プランはまだクエリキャッシュにある可能性があります。そうでない場合は、新しい計画を作成する必要があります。
- サーバーは指定されたとおりにクエリを実行し、結果をクライアントに返します。
- その結果には、実装に依存する行のバッファーが含まれます。 100行以上またはそれ以下の場合があります。行ごとにすべての列が返されます;
- より多くの行をフェッチすると、最終的にクライアントはサーバーにさらに行を要求します。これは、クライアントが不足した場合、またはプリエンプティブに実行された場合です。繰り返しますが、これは実装に依存します。
このすべてのアイデアは、多すぎるを返送せずに、サーバーへのラウンドトリップを最小限に抑えることです。 不要なデータ。そのため、100万行を要求しても、一度にすべてを取り戻すことはできません。
LIMIT句(または実際には任意の句)は、結果セットを変更します。
最後に、(7)は重要です。SELECT * FROM table WHERE a = 'foo'
およびSELECT * FROM table WHERE a = 'bar'
データベースオプティマイザに関する限り、2つの異なるクエリであるため、実行プランはそれぞれ個別に決定する必要があります。ただし、パラメーター化されたクエリ(SELECT * FROM table WHERE a = :param
)パラメータが異なるのは1つのクエリであり、計画する必要があるのは1回だけです(少なくともクエリキャッシュから外れるまで)。