SQL 批量插入/BCP 导出后未释放已用内存

Meh*_*ANI 10 sql-server memory

我创建了一个非常基本的 SQL 表,如下所示

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]
Run Code Online (Sandbox Code Playgroud)

然后我执行了 3 Gig Bulk Insert

    BULK
    INSERT TickData
    FROM 
    'C:\SUMO.csv'
    GO
Run Code Online (Sandbox Code Playgroud)

然后 SQL 服务器的 RAM 使用量飙升,吃掉了大约 30Go 的 RAM:

在此处输入图片说明

在此处输入图片说明

我更愿意认为这是一种异常行为,可以采取措施来避免这种情况。

编辑:
好的,这似乎是默认行为。很公平。
但是,为什么在批量插入完成后很久没有释放内存

一些额外的考虑:
至于有关 SQL 服务器在操作系统“告知”时释放内存的评论,我在 24 核 32 Gb Xeon 服务器上的实践经验证明这是不准确的:一旦内存消耗大的 BCP 提取结束我有一个数据处理应用程序的 .Net 实例池,它们需要处理提取的数据,并且它们会窒息/争吵以共享剩余内存以尝试执行它们的工作,这比打开 SQL Server 需要更长的时间关闭,内存可供所有应用程序共享。我必须停止 SQL Server 代理才能使一切顺利进行,并防止应用程序因 Artiialt 导致的 OutOfMemmroy 异常而崩溃。至于人为的残酷内存上限/限制,如果有可用内存,为什么不使用它?理想情况下,它宁愿动态设置以适应可用的内容,而不仅仅是“随机”强制限制。但我想这是设计使然,所以案例在最后一点结束。

小智 12

SQL Server 将尽可能多的内存分配到其缓冲池中是正常行为。数据库在使用大量缓冲区时效果最佳。如果要更改行为,可以设置“最大服务器内存”设置。一些很好的背景阅读在这里。


Aar*_*and 7

如果您真的希望操作系统从 SQL Server 取回内存,请获取一个 20 GB 的大文件并通过网络复制它。SQL Server 将根据操作系统的需要释放内存。但是在此过程中,我会观察各种性能计数器,并查看如果在复制过程中或之后立即再次运行 BULK INSERT 的性能会如何变化。

如果要手动执行此操作,则应设置 SQL Server 的最大服务器内存设置的下限,然后重新启动服务。现在,即使 SQL Server 需要,它也不会使用 28GB。但这似乎是人为地限制了 SQL Server。

您似乎期望的是更灵活的行为,您可以在部分时间拥有空闲内存。出于什么目的?这是否类似于缩小数据库文件以释放磁盘空间,因为数据库文件将再次增长而不能用于其他目的?

有趣的是,如果您在 Google 上搜索“为什么不使用 SQL Server”,最常见的自动完成功能是“释放内存”。