Страницы считываются в память по мере необходимости. Если свободной памяти нет, самая старая неизмененная страница заменяется входящей страницей.
Это означает, что если вы выполняете запрос, который требует больше данных, чем может поместиться в памяти, многие страницы будут жить в памяти очень недолго, что приведет к большому количеству операций ввода-вывода.
Вы можете увидеть этот эффект, посмотрев на счетчик «Продолжительность жизни страницы» в системном мониторе Windows. Посмотрите на https://sqlperformance.com/2014/10/sql-performance/knee-jerk-page-life-expectancy некоторые подробности об этом счетчике.
В комментариях вы конкретно спросили, что происходит, когда результаты запроса превышают доступное пространство буфера. Возьмите простейший пример select * from some_very_big_table;
- предположим, что таблица имеет max server memory (MB)
размер 32 ГБ и настроена на 24 ГБ. Все 32 ГБ табличных данных будут считываться на страницы в буфере страниц по одной защелкой, отформатированные в сетевые пакеты и отправленные по сети. Это происходит постранично; Вы могли бы одновременно выполнить 300 таких запросов, и при условии, что блокирования не было, данные для каждого запроса будут считываться в буферное пространство страницы, страницу за раз, и выводиться на связь так быстро, как может клиент запрашивать и потреблять данные. Как только все данные с каждой страницы были отправлены на провод, страница становится незапертой и очень быстро заменяется какой-либо другой страницей с диска.
В случае более сложного запроса, скажем, например, агрегирования результатов из нескольких таблиц, страницы будут загружаться в память точно так же, как указано выше, как того требует процессор запросов. Если обработчику запросов требуется временное рабочее пространство для вычисления результатов, он будет знать об этом заранее, когда будет составлять план для запроса, и запросит рабочее пространство (память) из SQLOS . SQLOS в какой-то момент (при условии, что время не истекает ) выделит эту память обработчику запросов, после чего обработка запросов возобновится. Если обработчик запросов ошибается в оценке объема памяти, запрашиваемого у SQLOS, ему может потребоваться выполнить «разлив на диск»операция, при которой данные временно записываются в базу данных tempdb в промежуточной форме. Страницы, которые были записаны в базу данных tempdb, будут разблокированы после их записи в базу данных tempdb, чтобы освободить место для чтения других страниц в памяти. В конце концов, процесс запроса вернется к данным, хранящимся в базе данных tempdb, с разбивкой по страницам при использовании фиксации, на страницы в буфере, помеченные как свободные.
Я, несомненно, пропускаю множество очень технических деталей в приведенном выше резюме, но я думаю, что это отражает суть того, как SQL Server может обрабатывать больше данных, чем помещается в памяти.