Как SQL Server обрабатывает данные для запроса, если в буферном кеше недостаточно места?


10

Мой вопрос заключается в том, как SQL Server обрабатывает запрос, который должен вытянуть больший объем данных в буферный кеш, чем есть доступное пространство? Этот запрос будет содержать несколько объединений, поэтому результирующий набор не существует в этом формате уже на диске, и ему потребуется скомпилировать результаты. Но даже после компиляции все равно требуется больше места, чем доступно в буферном кеше.

Я приведу пример. Предположим, у вас есть экземпляр SQL Server, который имеет 6 ГБ свободного пространства в буфере кэша. Я запускаю запрос с несколькими объединениями, который считывает 7 ГБ данных. Как SQL Server может ответить на этот запрос? Временно ли он хранит данные в базе данных tempdb? Это терпит неудачу? Делает ли он что-то, что просто читает данные с диска и компилирует сегменты одновременно?

Кроме того, что произойдет, если я попытаюсь вернуть 7 ГБ общих данных, это изменит то, как SQL Server обрабатывает это?

Мне уже известно о нескольких способах решения этой проблемы, мне просто любопытно, как SQL Server внутренне обрабатывает этот запрос, когда он выполняется, как указано.

Кроме того, я уверен, что эта информация где-то существует, но мне не удалось ее найти.


1
С точки зрения непрофессионала, SQL Server будет хранить рабочие таблицы и результаты собственной внутренней обработки в базе данных tempdb. Страницы читаются с диска при необходимости. Страницы будут оставаться в памяти до тех пор, пока они не будут вытеснены или когда SQL будет готов зафиксировать их на диске. Это когда вы запускаете большой запрос tempdb будет расти. Я видел, как запросы ставят систему на колени, потому что tempdb позволяли расти без контроля и занимали все оставшееся место на диске. Я знаю, что это не на 100% точно, просто пытаюсь объяснить это просто. Часть, которая использует данные, не является частью, которая управляет расположением этих данных
datagod

Ответы:


13

Страницы считываются в память по мере необходимости. Если свободной памяти нет, самая старая неизмененная страница заменяется входящей страницей.

Это означает, что если вы выполняете запрос, который требует больше данных, чем может поместиться в памяти, многие страницы будут жить в памяти очень недолго, что приведет к большому количеству операций ввода-вывода.

Вы можете увидеть этот эффект, посмотрев на счетчик «Продолжительность жизни страницы» в системном мониторе 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 может обрабатывать больше данных, чем помещается в памяти.


Из любопытства, какой запрос тянет 7 ГБ данных? Я надеюсь, что это пакетный процесс.
датагод

Вероятно, не так много, и вы правы, надеюсь, это будет пакетный процесс. Мне было просто интересно посмотреть, как SQL будет обрабатывать этот запрос
Дастин

5

Я не могу говорить о том, что именно ваш запрос будет делать в этом сценарии, но SQL Server имеет несколько вариантов в зависимости от того, сколько нужно.

  • Данные могут «пролиться» на TempDB, это будет использовать ваш диск
  • Старые страницы могут быть вытеснены из вашего буферного кеша
  • SQL Server может загрузить некоторые страницы в буферный кеш, использовать их, а затем вращать новые страницы в

Лучший способ узнать, что произойдет, - создать сценарий в среде разработчика и выяснить это.


2

У меня вопрос, как SQL Server обрабатывает запрос, который должен вытянуть больший объем данных в буферный кеш, чем есть свободное место

Чтобы ответить на эту конкретную часть, позвольте мне рассказать вам, как это делается. Страницы имеют размер 8 КБ. Когда вы запускаете запрос, запрашивающий большой набор данных и требующий, чтобы многочисленные страницы были введены в память, SQL Server не будет приводить все страницы за один раз. Он найдет определенные страницы и принесет по одной 8КБ-страницы в память, прочитает данные из нее и даст вам результат, и теперь это будет продолжаться, если предположить, что он сталкивается с ситуацией, когда памяти меньше, в этом случае старые страницы будут сброшены диск как @Max указал. Как вы уже догадались, эта нехватка памяти может замедлить процесс, поскольку некоторое время будет потрачено на удаление старых страниц. Это где контрольно-пропускной пункт и Lazywriterвходит в картину. Ленивый писатель должен убедиться, что всегда есть немного свободной памяти, чтобы принести новые страницы на диск. При обнаружении низкого свободного буфера он срабатывает и создает свободные места для новых страниц.

РЕДАКТИРОВАТЬ

Я понял это, но часть, которая немного сбивает меня с толку, - это то, что происходит, если вы объединяете \ фильтруете данные, и эти результаты превышают размер кэша.

Память для объединения и фильтрации определяется еще до того, как запрос будет выполнен, и предположим, что действительно происходит нехватка памяти, а память, необходимая для выполнения операции, недоступна. Процессор SQL Server предоставит «необходимую память», которая

Требуемая память: минимальное количество памяти, необходимое для запуска сортировки и хэш-соединения. Это называется обязательным, потому что запрос не запустился бы без этой доступной памяти. SQL-сервер использует эту память для создания внутренних структур данных для обработки сортировки и хэш-соединения.

Так что, по крайней мере, запрос начнет выполняться, но во время выполнения вполне вероятно, что промежуточный результат передается в Tempdb, что делает его медленным. Я настоятельно рекомендую вам прочитать Понимание Query Memory Grant


Я понял это, но часть, которая немного сбивает меня с толку, - это то, что происходит, если вы объединяете \ фильтруете данные, и эти результаты превышают размер кэша. Данные должны быть скомпилированы для получения возвращаемого набора, но возвращаемый набор превышает размер кэша. Продолжает ли внутренне циклически перебирать страницы в кэше, пока не получится конечный результат? Я бы подумал, что он запишет результаты в базу данных tempdb, поскольку она превысила кэш, а затем прочитает это с диска, но не знает, так ли это
Дастин

2
@Dustin Отредактировал мой ответ, пожалуйста, проверьте
Shanky
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.