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

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

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

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

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

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

10 голосов | спросил Dustin 27 Jpm1000000pmFri, 27 Jan 2017 18:21:43 +030017 2017, 18:21:43

3 ответа


12

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

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

Этот эффект можно увидеть, посмотрев на счетчик «Ожидание жизни страницы» в Windows Performance Monitor. Посмотрите https://sqlperformance.com/2014/10/sql-performance/Ожидание продолжительности колена-страницы-жизни для получения подробной информации об этом счетчике.

В комментариях вы задали вопрос, что происходит, когда results запроса больше доступного пространства буфера. Возьмем самый простой пример: select * from some_very_big_table; - предположим, что таблица 32 ГБ, а max server memory (MB) настроен на 24 ГБ. Все 32 ГБ данных таблицы будут считаться на страницах в буфере страниц по одному, зафиксированы , отформатированы в сетевые пакеты и отправлены по кабелю. Это происходит по страницам; у вас могло бы быть 300 таких запросов одновременно, и если предположить, что не происходит блокировки, данные для каждого запроса будут считываться в пространство буфера страниц, страницу за раз и помещаться в провод так быстро, как клиент может запросить и использовать данные. После того как все данные с каждой страницы были отправлены на провод, страница будет разблокирована и очень быстро будет заменена другой страницей с диска.

В случае более сложного запроса, скажем, например, агрегирования результатов из нескольких таблиц, страницы будут выведены в память точно так же, как указано выше, как это требуется процессору запросов. Если процессору запросов требуется временное рабочее пространство для вычисления результатов, он будет знать это заранее, когда он компилирует план запроса, и запросит рабочее пространство (память) из SQLOS . SQLOS будет в какой-то момент (при условии, что это не ), предоставить эту память процессору запросов, после чего возобновится обработка запросов. Если процессор запросов ошибочно оценивает, сколько памяти запрашивается у SQLOS, возможно, потребуется выполнить " разлить на диск ", где данные временно записываются в tempdb в промежуточной форме. Страницы, которые были записаны на tempdb, будут разблокированы после их записи в tempdb, чтобы освободить место для чтения других страниц. В конце концов процесс запроса вернется к данным, хранящимся в tempdb, подкачки, которые при использовании блокировки, на страницы в буфере, которые отмечены бесплатно.

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

ответил Max Vernon 27 Jpm1000000pmFri, 27 Jan 2017 18:41:12 +030017 2017, 18:41:12
5

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

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

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

ответил Arthur D 27 Jpm1000000pmFri, 27 Jan 2017 18:39:20 +030017 2017, 18:39:20
2
  

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

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

ИЗМЕНИТЬ

  

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

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

  

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

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

ответил Shanky 27 Jpm1000000pmFri, 27 Jan 2017 19:50:28 +030017 2017, 19:50:28

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132