Como o SQL Server lida com os dados de uma consulta em que não há espaço suficiente no cache do buffer?

10

Minha pergunta é como o SQL Server lida com uma consulta que precisa extrair mais volume de dados no cache do buffer do que o espaço disponível? Essa consulta conteria várias junções, portanto, o conjunto de resultados já não existe neste formato no disco e seria necessário compilar os resultados. Mas, mesmo após a compilação, ele ainda requer mais espaço do que o disponível no cache do buffer.

Vou dar um exemplo. Suponha que você tenha uma instância do SQL Server com 6 GB de espaço total no cache de buffer disponível. Eu executo uma consulta com várias associações que lê 7 GB de dados. Como o SQL Server pode responder a essa solicitação? Ele armazena temporariamente os dados no tempdb? Isso falha? Ele faz algo que apenas lê dados do disco e compila segmentos por vez?

Além disso, o que acontece se eu estiver tentando retornar 7 GB do total de dados, isso muda a maneira como o SQL Server lida com isso?

Eu já estou ciente de várias maneiras de resolver isso, apenas estou curioso para saber como o SQL Server lida com essa solicitação internamente quando é executada conforme indicado.

Além disso, tenho certeza de que essas informações existem em algum lugar, mas não consegui encontrá-las.

Dustin
fonte
11
Em termos leigos, o SQL Server armazenará as tabelas de trabalho e os resultados de seu próprio processamento interno em tempdb. As páginas são lidas do disco quando necessário. As páginas permanecerão na memória até serem forçadas a sair ou quando o SQL estiver pronto para enviá-las ao disco. É quando você executa uma consulta grande, o tempdb aumenta. Eu vi consultas deixar um sistema de joelhos porque o tempdb teve permissão para crescer desmarcado e consumiu todo o espaço restante na unidade. Eu sei que isso não é 100% exato, apenas tentando explicá-lo simplesmente. A parte que usa os dados não é a parte que gerencia a localização desses dados
datagod

Respostas:

13

As páginas são lidas na memória conforme necessário; se não houver memória disponível, a página não modificada mais antiga será substituída pela página de entrada.

Isso significa que, se você executar uma consulta que exija mais dados do que pode caber na memória, muitas páginas terão uma vida útil muito curta na memória, resultando em muitas E / S.

Você pode ver esse efeito consultando o contador "Expectativa de vida da página" no Windows Performance Monitor. Consulte https://sqlperformance.com/2014/10/sql-performance/knee-jerk-page-life-expectancy para obter ótimos detalhes sobre esse contador.

Nos comentários, você perguntou especificamente o que acontece quando os resultados da consulta são maiores que o espaço disponível no buffer. Pegue o exemplo mais simples, select * from some_very_big_table;- suponha que a tabela tenha 32 GB e max server memory (MB)esteja configurada em 24 GB. Todos os 32 GB de dados da tabela serão lidos nas páginas do buffer de páginas, uma de cada vez, travadas, formatado em pacotes de rede e enviado através do fio. Isso acontece página por página; você poderia ter 300 dessas consultas em execução ao mesmo tempo e, supondo que não houvesse bloqueio, os dados de cada consulta seriam lidos no espaço do buffer da página, uma página de cada vez, e colocados na conexão o mais rápido que o cliente puder solicitar e consumir os dados. Depois que todos os dados de cada página tiverem sido enviados para a conexão, a página será desbloqueada e será rapidamente substituída por outra página do disco.

No caso de uma consulta mais complexa, por exemplo, agregando resultados de várias tabelas, as páginas serão puxadas para a memória exatamente como acima, conforme exigido pelo processador de consultas. Se o processador de consultas precisar de espaço de trabalho temporário para calcular resultados, ele saberá disso antecipadamente quando compilar um plano para a consulta e solicitará espaço de trabalho (memória) do SQLOS . O SQLOS, em algum momento (supondo que não atinja o tempo limite ), conceda essa memória ao processador de consultas, momento em que o processamento da consulta será retomado. Se o processador de consultas cometer um erro na estimativa de quanta memória solicitar do SQLOS, talvez seja necessário executar um "derramamento em disco"operação, onde os dados são temporariamente gravados no tempdb de forma intermediária. As páginas que foram gravadas no tempdb serão desbloqueadas quando forem gravadas no tempdb para dar espaço para outras páginas serem lidas na memória. Eventualmente, o processo de consulta retornará aos dados armazenados no tempdb, paginando os que usam travas, nas páginas do buffer marcadas como livres.

Sem dúvida, estou sentindo falta de muitos detalhes técnicos no resumo acima, mas acho que isso captura a essência de como o SQL Server pode processar mais dados do que cabem na memória.

Max Vernon
fonte
Por curiosidade, que tipo de consulta está obtendo 7 GB de dados? Espero que este seja um processo em lote.
datagod
Provavelmente não muitos, e você está certo, seria um processo em lote. Eu estava apenas curioso para ver como o SQL lidaria com essa solicitação.
Dustin
5

Não posso falar com o que exatamente sua consulta faria nesse cenário, mas o SQL Server tem várias opções, dependendo da quantidade necessária.

  • Os dados podem "derramar" para o TempDB, isso usaria seu disco
  • Páginas antigas podem ser removidas do cache do buffer
  • O SQL Server pode carregar algumas páginas para armazenar em buffer, usá-las e girar novas páginas no

A melhor maneira de descobrir o que aconteceria é criar o cenário em um ambiente de desenvolvimento e descobrir.

Arthur D
fonte
2

Minha pergunta é como o SQL Server lida com uma consulta que precisa extrair mais volume de dados no cache do buffer, para que haja espaço disponível

Para responder a esta parte específica, deixe-me dizer como isso é gerenciado. As páginas são de tamanho 8KB. Quando você executa uma consulta solicitando um grande conjunto de dados e que exige que várias páginas sejam trazidas para a memória, o SQL Server não trará todas as páginas de uma só vez. Ele localizará as páginas específicas e trará uma a uma páginas de 8 KB na memória, lerá os dados e fornecerá o resultado, e isso continuará agora, suponha que esteja enfrentando uma situação em que a memória é menor. Nesse caso, as páginas antigas serão liberadas para o disco como @Max apontou. Como você adivinhou corretamente, essa pouca memória pode atrasar as coisas, pois seria gasto algum tempo na remoção de páginas antigas. É aqui que o ponto de verificação e o Lazywriterentra em cena. O Lazywriter é para garantir que sempre haja memória livre para trazer novas páginas para o disco. Quando um buffer com pouca disponibilidade é encontrado, ele é acionado e cria espaços livres para serem novas páginas.

EDITAR

Entendi, mas a parte que mais me impressiona é o que acontece se você estiver juntando \ filtragem de dados e esses resultados excederem o tamanho do cache.

A memória para ingressar e filtrar é decidida antes mesmo da execução da consulta, e suponha que haja realmente uma trituração de memória e a memória necessária para executar a operação não esteja disponível O processador do SQL Server concederá a "memória necessária", que é

Memória necessária: Memória mínima necessária para executar a classificação e a junção de hash. É chamado obrigatório porque uma consulta não seria iniciada sem essa memória disponível. O servidor SQL usa essa memória para criar estruturas de dados internas para lidar com a classificação e a associação de hash.

Portanto, pelo menos, a consulta começará a ser executada, mas durante o tempo de execução, é bem provável que o resultado intermediário seja derramado no Tempdb, tornando-o lento. Eu sugiro fortemente que você leia Noções básicas sobre concessão de memória de consulta

Shanky
fonte
Entendi, mas a parte que mais me impressiona é o que acontece se você estiver juntando \ filtragem de dados e esses resultados excederem o tamanho do cache. Os dados precisariam ser compilados para produzir o conjunto de retorno, mas o conjunto de retorno é maior que o tamanho do cache. Ainda é possível percorrer internamente as páginas pelo cache até produzir o resultado final? Meu pensamento seria que ele iria escrever os resultados para tempdb, uma vez que excedeu o cache e, em seguida, ler a partir do disco que, mas não sei se esse é o caso
Dustin
2
@Dustin Editado minha resposta, por favor, verifique
shanky