Estou executando um SQL Server 2017 Enterprise no local no nível de patch/CU mais recente que dá suporte ao software do fornecedor, que se tornará importante mais tarde.
Estatísticas do servidor:
- Máquina virtual (a memória está fixada )
- Datacenter do Windows Server 2016
- 16 vCPU
- 192 GB de RAM (179 GB alocados ao SQL Server)
- Arquivo de página de 30 GB (prefiro que isso não esteja lá, mas não foi uma batalha que ganhei)
- Hospeda 5 bancos de dados de usuários, 1 dos quais tem aproximadamente 4 TB de tamanho
- Servidor Obrigatório do Fornecedor Padrão de 1 para
max degree of parallelism
Como dito acima, este sistema suporta uma plataforma de fornecedor popular e, embora o fornecedor seja muito bom sobre índices personalizados ou outros ajustes de modelo de dados transparentes, eles tendem a desaprovar alterações de funcionalidade que exigem ajustes em seu código de aplicativo (por razões óbvias, pois afetaria milhares de seus clientes).
A situação que estou enfrentando é que esse aplicativo de fornecedor executa row mode
consultas de longa duração que enfileiram uma lista de itens que são processados item por item em seu código de aplicativo. Essas consultas podem (e funcionam) ser executadas por dias ou até semanas se as permitirmos (mostrando ASYNC_NETWORK_IO
esperas, como esperado). Quando essas consultas são iniciadas, elas solicitam grandes quantidades SerialDesiredMemory
em comparação com o SerialRequiredMemory
que realmente precisam. O resultado é que a Memória Solicitada/Concedida no administrador de MEMORYCLERK_SQLQERESERVATIONS
memória excede em muito o que é Usado. Por exemplo:
-- What amount of query execution memory is asked for and used
SELECT SUM(granted_memory_kb) / 1024 AS granted_memory_mb
, SUM(requested_memory_kb) / 1024 AS requested_memory_mb
, SUM(used_memory_kb) / 1024 AS used_memory_mb
, (SUM(granted_memory_kb) - SUM(used_memory_kb)) / 1024 AS excess_memory_grant_mb
FROM sys.dm_exec_query_memory_grants
OPTION (RECOMPILE)
Devoluções:
Isso é absolutamente aterrorizante E isso ocorre depois de habilitar RESOURCE GOVERNOR
e reduzir o REQUEST_MAX_MEMORY_GRANT_PERCENT
pool de recursos em que essas consultas caem para 5
%, embora eu provavelmente reduza isso até o mínimo de 1
% do SQL 2017 com base no que estou vendo.
Minha pergunta é enquanto estou preso no SQL 2017, há mais alguma coisa que eu possa fazer para limitar a quantidade de RAM desperdiçada em meus planos de execução de consulta, além de reduzir ainda mais o REQUEST_MAX_MEMORY_GRANT_PERCENT
valor do pool de recursos para 1
%?
Como este é um aplicativo de fornecedor, os guias de plano de consulta podem ser uma opção, mas o ajuste MAX_GRANT_PERCENT
não me dá nada além do que estou obtendo ao ajustar o REQUEST_MAX_MEMORY_GRANT_PERCENT
valor no pool de recursos. Existe algo que eu possa fazer em um guia de plano para forçar a batch mode
execução na esperança de que isso acione o recurso de feedback de memória do modo de lote que está disponível no SQL 2017? Novamente, como este é o código do aplicativo do fornecedor com o qual estou trabalhando, não tenho a capacidade de alterar as consultas, portanto, as abordagens padrão de tolice provavelmente não funcionarão aqui.
Atualizar para o SQL 2019 (ou preferencialmente SQL 2022) é a resposta óbvia aqui, pois me dá acesso a vários recursos que posso empregar nessa situação, como Row Mode Memory Feedback e valores de ponto flutuante paraREQUEST_MAX_MEMORY_GRANT_PERCENT
, mas existem outras opções disponíveis com o SQL 2017 que ainda não toquei? Se não, tudo bem, estou apenas tentando esgotar todas as opções pendentes que ainda não pensei.