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.
Respostas:
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 emax 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.
fonte
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.
A melhor maneira de descobrir o que aconteceria é criar o cenário em um ambiente de desenvolvimento e descobrir.
fonte
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
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 é
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
fonte