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