Eu criei uma tabela SQL muito básica da seguinte maneira
CREATE TABLE [dbo].[TickData](
[Date] [varchar](12) NULL,
[Time] [varchar](12) NOT NULL,
[Symbol] [varchar](12) NOT NULL,
[Side] [varchar](2) NOT NULL,
[Depth] [varchar](2) NOT NULL,
[Quote] [varchar](12) NOT NULL,
[Size] [varchar](18) NOT NULL
) ON [PRIMARY]
Em seguida, realizei uma inserção em massa de 3 GB
BULK
INSERT TickData
FROM
'C:\SUMO.csv'
GO
Em seguida, o uso da RAM para o servidor SQL disparou, consumindo ~ 30Go de RAM:
Prefiro pensar que este é um comportamento anormal e que medidas podem ser tomadas para evitar isso.
EDIT:
Ok, este parece ser o comportamento padrão. Justo.
No entanto, por que a memória não é liberada muito tempo após o término da inserção em massa?
Algumas considerações extras:
Como nos comentários sobre o SQL Server que libera a memória quando o sistema operacional recebe instruções, minha experiência prática em um servidor Xeon de 24 Gb e 32 Gb prova que isso é inexato: Depois que uma extração de BCP com memória voraz termina Eu tenho um pool de instâncias .net do meu aplicativo de processamento de dados que precisam processar os dados extraídos e eles ficam sufocados / lutando para compartilhar a memória restante para tentar executar seus trabalhos, o que leva muito mais tempo que quando o SQL Server é ativado desligado e a memória está disponível para todos os aplicativos para compartilhar. Eu tenho que parar o SQL Server Agent para que tudo corra bem e impedir que os aplicativos falhem no Articiallt causado pela exceção OutOfMemmroy. Quanto ao limite / limitação artificial da memória brutal, se houver memória livre disponível, por que não usá-lo? Idealmente, preferiria ser definido dinamicamente para se adaptar ao que está disponível, em vez de apenas ser limitado à força "aleatoriamente". Mas eu acho que isso é por projeto, então caso encerrado neste último ponto.
fonte
Respostas:
É um comportamento normal do SQL Server alocar o máximo de memória possível para seu buffer pool. Bancos de dados funcionam melhor com muito buffer. Se você deseja alterar o comportamento, pode definir a configuração 'max server memory' . Alguma boa leitura de fundo sobre isso está aqui.
fonte
Se você realmente deseja que o sistema operacional retire a memória do SQL Server, pegue um grande arquivo de 20 GB e copie-o pela rede. O SQL Server liberará a memória conforme o sistema operacional precisar. Mas eu observaria uma variedade de contadores de desempenho enquanto isso acontecia e veria como o desempenho do seu BULK INSERT muda se você executá-lo novamente enquanto a cópia está em andamento ou imediatamente após.
Se você quiser fazer isso manualmente, defina um limite inferior na configuração de memória máxima do servidor do SQL Server e reinicie o serviço. Agora, o SQL Server não usará 28 GB, mesmo que seja necessário. Mas isso parece limitar artificialmente o SQL Server.
O que você espera é um comportamento mais flexível, onde você pode ter memória livre parte do tempo. Para qual propósito? É como diminuir um arquivo de banco de dados para liberar espaço em disco que você não pode usar para outros fins, porque o arquivo de banco de dados crescerá novamente?
É engraçado, se você digitar uma pesquisa no Google por "por que o SQL Server não", o preenchimento automático mais comum é "liberar memória".
fonte
Infelizmente, isso é por design; consulte esta postagem. No entanto, neste post, ele fornece algumas instruções sobre como controlá-lo.
/server/251832/sql-server-bulk-insert-physical-memory-issue
Alocação de Memória
A memória não está
freed
ativa porque aloca muito a memória como um aplicativo .NET. Como a alocação de memória é cara, ela será mantida, a menos que o SO solicite. Mas, não tema, se o sistema operacional desejar a memória, ela será obtida, exatamente como em um aplicativo .NET.fonte