我遇到了以前从未遇到的SQL Server Express问题。
我有一个包含3200万行的表,此列设置为:
[Insp_ID] [nvarchar](8) NOT NULL,
[NodeID] [int] NULL,
[NodeVisible] [bit] NULL,
[Note] [nvarchar](max) NULL,
[Points] [int] NULL,
[QST_ID] [int] NULL,
[QST_Num] [int] NOT NULL,
[Response_Num] [int] NOT NULL,
[Value] [nvarchar](max) NULL,
[ValueID] [int] NULL,
[ValueVisible] [bit] NULL,
CONSTRAINT [QST2D_PK_i83] PRIMARY KEY CLUSTERED
([Insp_ID] ASC, [QST_Num] ASC, [Response_Num] ASC)
该表大约是1900 MB,或者甚至可能更大一些。这很难分辨,因为我几乎不能在桌面上进行任何维护操作而不会出现此错误:
Msg 802缓冲池中没有足够的可用内存。
据我了解,SQL Server Express获得1GB。当我尝试更改主键或执行DBCC DBREINDEX
时会发生这种情况。我可以从数据库中获取信息并返回的唯一方法是使用BCP,这非常不方便(但是,它很有意思,它的工作原理)。 BCP允许我重组表(即PK),然后重新输入数据。
无论如何,进一步的实验:我将行数减少到8.2M,整个表大小减少到大约633MB。仍然得到相同的错误,没有足够的内存。这令人困惑,因为这对我来说似乎不是很多数据。
此时,我删除了两个nvarchar(max)
列,这进一步将表格大小减小到大约540MB。那时,我不再耗尽记忆。
我无法判断缓冲区是否在抱怨行数或表大小,但感觉就像基于这个轶事证据的表大小一样。
有没有人对此有解决方案或见解?我觉得我们正在使用SQL Server Express咆哮错误的树 - 这太糟糕了,因为到目前为止它完全符合我们的需求。
答案 0 :(得分:1)
根据以往的经验,SQL Server Express的上限为1GB,并且还有数据库大小限制,这取决于您使用的版本。
有一个关于Limitations of SQL Server Express的关于here的上一个帖子可能有助于解决一般问题。
虽然在MSDN上采取了一个爱管闲事的方式,但我找到了一个很好的小文本补丁,我相信这可能对你有所帮助:
SQL Server需要足够的内存来将数据保存在内存优化的表和索引中。要考虑行版本,您应该提供的内存量是内存优化表和索引的预期大小的两倍。但实际需要的内存量取决于您的工作量。您应该监视内存使用情况并根据需要进行调整。内存优化表中的数据大小不得超过池的允许百分比。
要发现内存优化表的大小,请参阅Max rows in a SQL table?了解如何获取它(适用于SQL 2014)。
其他可能有用的文章有Maximum Capacity Specifications for SQL Server或{{3}}。
答案 1 :(得分:1)
我在微软论坛上问了一个类似的问题,并被告知2014年不支持DBCC DBREINDEX。我发现这很奇怪,因为它有效...... 有时候。但是,我不能打折语言障碍。而且,每次我尝试过类似的声明:
ALTER INDEX ALL ON QST2D REBUILD;
它有效。即使我运行此查询时:
SELECT
CASE
WHEN database_id = 32767 THEN 'mssqlsystemresource'
ELSE DB_NAME(database_id)
END AS [Database],
CONVERT(numeric(38,2),(8.0 / 1024) * COUNT(*)) AS [MB in buffer cache]
FROM sys.dm_os_buffer_descriptors
GROUP BY database_id
ORDER BY 2 DESC;
它在该数据库上使用了相当多的内存:
在重建过程中我一直刷新查询,我看到它从其他数据库中窃取内存,直到它们留下了微薄的空间。令我感到惊讶的是,语句因使用那么多内存而消失,但是我对SQL的内存管理知之甚少,无法判断这只是缓冲池还是许多其他池(可能包括缓冲池)。我很高兴它有效,到目前为止似乎可靠。
关键是,这适用于2 + GB表,31M +行和3字段复合键。这更符合我的预期。我仍然没有清楚地理解为什么DBCC DBREINDEX失败但改变索引没有,当我相信他们做类似的事情。它可能是如何完成的,即一个原子操作而不是单独的drop + create。也许组合操作一次性使用更多资源。我可能会尝试跟踪数据库,而这只是为了我自己的启发,但由于我似乎已经解决了我的直接问题,我想我应该标记这个答案。