【问题标题】:How can I determine the max usable size for my SQL Server Express tables?如何确定我的 SQL Server Express 表的最大可用大小?
【发布时间】:2015-04-27 20:04:29
【问题描述】:

我遇到了以前从未遇到过的 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 找错了树 - 这太糟糕了,因为到目前为止它完全符合我们的需求。

【问题讨论】:

  • 更多信息:同一个数据库有另一个表,大小略高于 1GB,有 103,000 行。能够毫无问题地重新索引这个。所以,我不知道缓冲池如何使用内存,但现在感觉就像是表大小(总 MB)和行数的组合。
  • 请记住,SQL Express 的 RAM 上限为 1 GB

标签: sql sql-server sql-server-2014


【解决方案1】:

根据过去的经验,SQL Server Express 的 RAM 上限为 1GB,并且还有一个数据库大小限制,具体取决于您使用的版本。

在 SO 上有一个关于 Limitations of SQL Server Express 的先前帖子,这可能有助于解决一般问题。

在 MSDN 上多管闲事时,我发现了一小段文字,我相信它可能会对您有所帮助:

SQL Server 需要足够的内存来保存内存优化表和索引中的数据。要考虑行版本,您应该提供两倍于内存优化表和索引的预期大小的内存量。但实际所需的内存量将取决于您的工作量。您应该监控您的内存使用情况并根据需要进行调整。内存优化表中的数据大小不得超过池的允许百分比。

要了解内存优化表的大小,请参阅here 了解如何获取它(适用于 SQL 2014)。

其他可能有用的文章是Max rows in a SQL table?Maximum Capacity Specifications for SQL Server

【讨论】:

    【解决方案2】:

    我在 Microsoft 论坛上问了一个类似的问题,并被告知 DBCC DBREINDEX 在 2014 年不受支持。我觉得这很奇怪,因为它可以工作......有时。但是,我不能忽视语言障碍。而且,每次我都尝试过类似的说法:

    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 的内存管理知之甚少,无法判断这只是缓冲池还是许多其他池(可能包括缓冲池)。我很高兴它可以工作,并且到目前为止似乎是可靠的。

    关键是,这适用于具有 31M+ 行和 3 字段复合键的 2+GB 表。这更像是我的预期。当我相信他们做类似的事情时,我仍然不清楚为什么 DBCC DBREINDEX 失败但 alter index 没有。这可能是它的完成方式,即一个原子操作而不是单独的 drop + create。也许合并操作一次性使用更多资源。我可能会尝试跟踪数据库,而这只是为了我自己的启迪,但由于我似乎已经解决了我的直接问题,我认为我应该将此标记为已回答。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多