必要に応じてページがメモリに読み込まれ、使用可能な空きメモリがない場合は、変更されていない最も古いページが着信ページに置き換えられます。
つまり、メモリに収まらないほど多くのデータを必要とするクエリを実行すると、多くのページがメモリ内で非常に短い期間しか存続せず、大量のI / Oが発生します。
この影響は、Windowsパフォーマンスモニターの "ページの期待寿命"カウンターで確認できます。そのカウンターの詳細については、https: //sqlperformance.com/2014/10/sql-performance/knee-jerk-page-life-expectancyをご覧ください。
コメントでは、クエリの結果が使用可能なバッファスペースよりも大きい場合にどうなるかを具体的に尋ねました。最も単純な例をselect * from some_very_big_table;
考えてみましょう-テーブルが32GBでありmax server memory (MB)
、24GBで構成されていると仮定します。すべての32GBのテーブルデータが一度に1つずつページバッファーのページに読み込まれ、ラッチされます。、ネットワークパケットにフォーマットされ、ネットワーク経由で送信されます。これはページごとに発生します。このようなクエリを同時に300個実行することができ、ブロッキングが発生していないと仮定すると、各クエリのデータは、ページバッファスペースに一度に1ページずつ読み込まれ、クライアントができる限り速くネットワークに送信されます。データをリクエストして使用します。各ページのすべてのデータがネットワークに送信されると、ページのラッチが解除され、すぐにディスクの他のページに置き換えられます。
より複雑なクエリの場合、たとえば複数のテーブルからの結果を集計する場合など、ページはクエリプロセッサが必要とするため、上記とまったく同じようにメモリに読み込まれます。クエリプロセッサが結果を計算するために一時的なワークスペースを必要とする場合は、クエリのプランをコンパイルするときにそのことを事前に認識し、SQLOSにワークスペース(メモリ)を要求します。SQLOSは、ある時点で(タイムアウトにならない場合)、そのメモリをクエリプロセッサに許可します。その時点でクエリ処理が再開されます。クエリプロセッサがSQLOSに要求するメモリ量の見積もりを間違えた場合、「ディスクへのスピル」を実行する必要がある場合があります。操作。データは一時的な形式でtempdbに一時的に書き込まれます。tempdbに書き込まれたページは、tempdbに書き込まれるとラッチが解除され、他のページをメモリに読み込むためのスペースが確保されます。最終的に、クエリプロセスはtempdbに格納されているデータに戻り、ラッチを使用してページングされ、空きとしてマークされているバッファー内のページに戻ります。
上記の要約では、非常に多くの技術的な詳細が欠落していることは間違いありませんが、SQL Serverがメモリに収まりきらないデータを処理する方法の本質を捉えていると思います。