J'ai créé une table SQL très basique comme suit
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]
J'ai ensuite effectué une insertion en vrac de 3 Go
BULK
INSERT TickData
FROM
'C:\SUMO.csv'
GO
Ensuite, l'utilisation de la RAM pour le serveur SQL est passée à Skyrock, mangeant environ 30 Go de RAM:
Je préfère penser qu'il s'agit d'un comportement anormal et que des mesures peuvent être prises pour éviter cela.
EDIT:
Ok, cela semble être le comportement par défaut. C'est suffisant.
Cependant, pourquoi la mémoire n'est-elle pas libérée longtemps après la fin de l'insertion en bloc?
Quelques considérations supplémentaires:
En ce qui concerne les commentaires concernant le serveur SQL libérant de la mémoire lorsqu'elle est "informée" par le système d'exploitation, mon expérience pratique sur un serveur Xeon à 24 cœurs 32 Go prouve que cela est inexact: une fois qu'un extrait BCP Memory-Voracious est terminé J'ai un pool d'instances .Net de mon application de traitement de données qui doivent traiter les données extraites, et elles sont étouffées / se battent pour partager la mémoire restante pour essayer d'effectuer leurs travaux, ce qui prend plus de temps que lorsque SQL Server est tourné désactivé et la mémoire est disponible pour toutes les applications à partager. Je dois arrêter l'Agent SQL Server pour que tout se passe bien et empêcher les applications de se bloquer pour Articiallt, à l'origine de l'exception OutOfMemmroy. En ce qui concerne le plafonnement / limitation de la mémoire brutale artificielle, si la mémoire libre est disponible, pourquoi ne pas l'utiliser? Idéalement, il serait préférable de s'adapter de manière dynamique à ce qui est disponible plutôt que d'être limité de manière "aléatoire". Mais je suppose que cela est intentionnel, donc le dossier est clos sur ce dernier point.
la source
Réponses:
Il est normal que SQL Server alloue autant de mémoire que possible dans son pool de tampons. Les bases de données fonctionnent mieux avec beaucoup de mémoire tampon. Si vous souhaitez modifier le comportement, vous pouvez définir le paramètre «mémoire maximale du serveur» . Une bonne lecture de fond à ce sujet est ici.
la source
Si vous voulez vraiment que le système d'exploitation récupère la mémoire de SQL Server, prenez un gros fichier de 20 Go et copiez-le sur le réseau. SQL Server libère la mémoire selon les besoins du système d'exploitation. Mais je regarderais une variété de compteurs de performances pendant que cela se passe et je verrais comment les performances de votre BULK INSERT changent si vous l'exécutez à nouveau pendant la copie ou immédiatement après.
Si vous souhaitez le faire manuellement, vous devez définir une limite inférieure sur le paramètre de mémoire maximale du serveur SQL Server et redémarrer le service. Désormais, SQL Server n'utilisera pas 28 Go même s'il en a besoin. Mais cela semble limiter artificiellement SQL Server.
Ce que vous semblez attendre, c'est un comportement plus flexible, où vous pouvez avoir de la mémoire libre une partie du temps. Dans quel but? Est-ce comme réduire un fichier de base de données pour libérer de l'espace disque que vous ne pouvez pas utiliser à d'autres fins parce que le fichier de base de données va se développer à nouveau?
C'est drôle, si vous tapez une recherche Google pour "pourquoi SQL Server ne fonctionne pas", l'auto-complétion la plus courante est "libérer de la mémoire".
la source
C'est malheureusement par conception, veuillez faire référence à ce post. Cependant, dans ce post, il vous donne des instructions sur la façon de le contrôler.
/server/251832/sql-server-bulk-insert-physical-memory-issue
Modification de l'allocation de mémoire
La mémoire n'est pas
freed
active car elle alloue beaucoup de mémoire comme une application .NET. Étant donné que l'allocation de mémoire est coûteuse, elle conservera cette allocation à moins que le système d'exploitation ne le demande. Mais n'ayez crainte, si le système d'exploitation veut la mémoire, il l'obtiendra, tout comme il le fait dans une application .NET.la source