Meu problema é que o SQL Server leva muito tempo para aumentar o uso de memória para instâncias com TB de RAM, enquanto temos esperas intermitentes de MEMORY_ALLOCATION_EXT que diminuem nosso processamento até que o SQL Server atinja sua memória máxima.
Temos instâncias clusterizadas de failover (FCI) do SQL Server 2019 Enterprise Edition com terabytes de memória nos nós. Em casos de uso usuais, permitimos apenas 1 instância do SQL Server por nó e, portanto, definimos a memória máxima do servidor perto de ~ 85% da memória no nó, mas também definimos a memória mínima do servidor relativamente baixa para o caso de failover do SQL Server para outro nó e precisa ser colocado on-line com um espaço de memória reduzido para se arrastar.
Estou ciente de que, se eu configurar a memória mínima mais alta, o SQL Server consumirá a memória de uma só vez.Acontece que o SQL Server não aloca a memória mínima na inicialização.- Estou ciente de que o SQL Server consumirá dinamicamente mais memória do sistema operacional conforme necessário e que, eventualmente, atingirá a memória máxima do servidor.
- Estou ciente de que executar uma grande consulta ou DBCC checkdb que extrai muitos dados forçará o SQL Server a consumir mais memória do sistema operacional.
Existem outras maneiras de forçar o SQL Server a aumentar seu uso de memória rapidamente?
O SQL Server não usará memória para o pool de buffers (seu maior uso) até precisar carregar páginas do armazenamento porque elas são referenciadas. A menos que você esteja fazendo algo estranho para tornar a alocação de memória lenta [†] , é improvável que seu atraso seja isso, mas lendo os dados que estão sendo alocados para reter. Suspeito que, ao mesmo tempo que essas esperas de alocação de memória, você tem esperas relacionadas a E/S correspondentes.
Para forçar o SQL Server a carregar coisas na memória e, portanto, alocar memória, se disponível e necessário, acesse as coisas para que elas precisem ser carregadas. Depois de iniciar sua instância SQL, execute uma carga de trabalho somente leitura para que o conjunto de trabalho comum normal do seu aplicativo seja carregado no pool de buffers.
Não apenas
SELECT * FROM HugeTable
porque isso provavelmente carregará um saldo ruim de dados (não o conjunto de trabalho principal dos aplicativos), portanto, o conjunto de trabalho principal ainda precisará ser carregado do disco/rede no próximo acesso de qualquer maneira, para que você tenha o mesmo IO atrasos. Além disso, seHugeTable
for realmente grande, o SQL Server pode ver que nem tudo caberá e não se incomodará em manter uma quantidade significativa na memória de qualquer maneira [‡].[†] Executando em uma VM em um host sobrecarregado, então o que parece RAM real são realmente páginas em disco?!
[‡] Em circunstâncias normais, você não deseja que uma varredura inesperada de tabela/índice em um objeto grande elimine todo o resto da memória. Um limite de quanto é mantido de um objeto para uma consulta é uma otimização para tentar impedir que isso aconteça).
Não, isso não está correto, a memória mínima do servidor não tem nada a ver com a rapidez com que o SQL Server a consumirá se definida. Memória mínima do servidor significa a quantidade mínima de memória, se consumida, após a qual o SQL Server não liberará memória abaixo desse valor em condições normais, se solicitado. Quando o valor mínimo do servidor for atingido, o SQL Server não cortará seus caches e liberará memória abaixo desse valor.
Sim correto, apenas para adicionar SQl Server em determinadas condições também pode consumir memória maior que o valor especificado em max server memory. Você deve ler o Guia de Gerenciamento de Memória
Existe outra maneira que força o SQL Server a reservar mais memória durante a inicialização e isso é chamado de " páginas grandes ". Este é um recurso da edição corporativa e permite que o SQL Server reserve rapidamente alguma memória livre durante a inicialização, a conta de serviço do SQL Server também deve ter páginas bloqueadas no privilégio de memória porque a alocação de páginas grandes é feita pela função VirtualAlloc() do sistema operacional Windows e o sistema operacional deve ter mais de 8 GB de RAM, se essas condições forem atendidas automaticamente A alocação de página grande está habilitada. Uma vez ativado, aparecerá como abaixo no log de erros
O tamanho normal da página de memória é de 4 KB no sistema X64, mas quando a página grande está habilitada, o tamanho será de 2 MB. Observe também que LargePageSupport é habilitado e usado pelo mecanismo mesmo se você não habilitar o sinalizador de rastreamento 834. Mas não é usada muita memória para isso e a memória do buffer pool não é usada, a menos que o sinalizador de rastreamento 834 esteja habilitado. Veja o blog compartilhado.