【发布时间】:2011-08-27 14:53:20
【问题描述】:
我目前正处于为我们的 CRM 应用程序中的一个大型模块计划重写的初始阶段。
我目前正在研究的一个领域是数据库优化,我还没有做出任何决定,但我只是想确保我正确理解 ROW_OVERFLOW_DATA 的概念 - http://msdn.microsoft.com/en-us/library/ms186981.aspx
我们使用的是 SQL server 2005,据我了解行大小限制为 8,060 字节,之后会发生溢出。
我运行了一个查询以获取特定读取密集型数据库的最大行大小
SELECT OBJECT_NAME (sc.[id]) tablename
, COUNT (1) nr_columns
, SUM (sc.length) maxrowlength
FROM syscolumns sc
join sysobjects so
on sc.[id] = so.[id]
WHERE so.xtype = 'U'
GROUP BY OBJECT_NAME (sc.[id])
ORDER BY SUM (sc.length) desc
这给了我几张 maxrowlength 略高于 8,000 但低于 10,000 的表。另一个查询显示平均行大小实际上非常小,大约 1,000 字节。
我的问题是:ROW_OVERFLOW_DATA 是基于每一行还是每一列?一旦扩大了 8,060 字节的限制,是导致它溢出的整个列移动到另一个页面还是只是特定的行?
例如,给定以下简化架构:
col1 (int) | col 2 (varchar (4000)) | col 3(varchar(5000))
1 | 4000 characters | 5000 characters ***This row is overflowing
2 | 4000 characters | 100 characters
3 | 150 characters | 150 characters
4 | 500 characters | 600 characters
第 1 行到第 4 行的第 3 列会被替换为 24 字节指针还是仅替换为 rowID 1?
我想知道因为如果每行都有一个指针,那么修复它就变得很重要,如果它只有几行,也许我们可以承受性能损失。
另外,我看到许多博客建议将可为空的列移到数据库的末尾,这样如果值实际上是 NULL,它们就不会占用任何行空间。这是真的?我们倾向于将时间戳和跟踪列保留在最后,因为它更容易可视化。现在我想知道我们是否不应该将它们进一步向上移动,因为它们永远不会为 NULL。
【问题讨论】:
标签: sql-server sql-server-2005 database-design optimization normalization