行内数据

更新日期: 2006 年 12 月 12 日

在 SQL Server 2005 中,小到中等大小的值类型(varchar(max)nvarchar(max)varbinary(max)xml)和大型对象 (LOB) 数据类型(textntextimage)都可以存储在数据行中。该行为可以通过在 sp_tableoption 系统存储过程中使用以下两个选项来控制:用于大型值类型的 large value types out of row 选项,以及用于大型对象类型的 text in row 选项。这两个选项最适用于这样的表:其中上述任意一种数据类型的数据值通常在一个单元中读/写,并且引用表的大多数语句都将引用此类数据。在行内存储的数据不一定有用,这取决于使用情况或工作负荷特征。

ms189087.note(zh-cn,SQL.90).gif重要提示:
在 SQL Server 的未来版本中将删除 text in row 选项。避免在新的开发工作中使用该选项,并计划修改当前使用 text in row 的应用程序。建议使用 varchar(max)nvarchar(max)varbinary(max) 数据类型存储大型数据。若要控制这些数据类型的行内和行外行为,请使用 large value types out of row 选项。

除非 text in row 选项设置为 ON 或特定的行内限制,否则 textntextimage 字符串都将是在数据行外存储的大型字符或二进制字符串(最多 2 GB)。数据行只包括一个 16 字节的文本指针,该指针指向一个内部指针构成的树的根节点。这些指针映射存储字符串片段的页。有关 textntextimage 字符串存储的详细信息,请参阅使用 Text 和 Image 数据

可以为包含 LOB 数据类型列的表设置 text in row 选项。还可以指定 text in row 选项限制,范围从 24 到 7,000 字节。

同样,除非 large value types out of row 选项设置为 ON,否则 varchar(max)nvarchar(max)varbinary(max)xml 列都存储在数据行中(如果可能)。在这种情况下,如果可以的话,数据库引擎将尝试容纳此特定值,否则会将其推到行外。如果 large value types out of row 设置为 ON,则上述值将存储在行外而只有 16 字节的文本指针存储在记录中。

ms189087.note(zh-cn,SQL.90).gif注意:
large value types out of row 设置为 OFF 时,用于大型值数据类型的最大行内存储量设置为 8,000 字节。与 text in row 选项不同,您不能指定表中列的行内限制。

将表配置为直接在数据行中存储大型值类型或大型对象数据类型时,如果存在以下情况之一,实际的列值都将存储在行内:

  • 字符串的长度比 textntextimage 列的指定限制短。
  • 数据行中有足够的可用空间容纳字符串。

当大型值类型或大型对象数据类型列值存储在数据行中时,数据库引擎不必访问单独的页或页集来读/写字符或二进制字符串。这便使读/写行内字符串的速度与读/写大小受限制的 varcharnvarcharvarbinary 字符串的速度大致一样。同样,当值存储在行外时,数据库引擎将引发读/写附加页。

对于大型对象数据类型,如果存储字符串所需的空间比 text in row 选项限制或行中的可用空间大,则本应存储在指针树根节点中的指针集将存储在行中。如果存在以下情况之一,指针将存储在行中:

  • 存储指针所需的空间量比 text in row 选项限制指定的空间量小。
  • 数据行中有足够的可用空间容纳指针。

当指针从根节点移至行本身时,数据库引擎不需要使用根节点。这样便可以在读/写字符串时不必访问页。从而可以提高性能。

如果使用根节点,它们将存储为 LOB 页中的一个字符串片段,并且最多可以包含 5 个内部指针。数据库引擎需要行具有 72 字节的空间来存储行内字符串的五个指针。如果 text in row 选项为 ON 或 large value types out of row 选项为 OFF 时行中没有足够的空间来容纳指针,数据库引擎可能必须分配一个 8K 的页来容纳它们。如果值的数据长度超过 40,200 字节,则需要 5 个以上的行内指针,此时只有 24 字节存储在主行中,而其他数据页被分配在 LOB 存储空间中。

当大型字符串存储在行中时,它们将与可变长度字符串的存储方式相似。数据库引擎将对列按大小以降序排序,并将值推到行外,直到剩余的列容纳在数据页 (8K) 中。

启用和禁用 large value types out of row 选项

可以按照下列方式通过使用 sp_tableoption 来为表启用 large value types out of row 选项:

sp_tableoption N'MyTable', 'large value types out of row', 'ON'

如果指定为 OFF,则 varchar(max)nvarchar(max)varbinary(max)xml 列的行内限制被设置为 8,000 字节。只有 16 字节的根指针存储在行内,而值存储在 LOB 存储空间中。对于其中大多数语句都不引用大型值类型列的表,建议将该选项设置为 ON。将这些列存储在行外意味着每页可以容纳更多的行,因此减少了扫描表所需的 I/O 操作的数量。

当该选项的值设置为 OFF时,许多字符串可能最终会存储在行内,从而可能减少每页上容纳的数据行数。如果引用表的大多数语句都不访问 varchar(max)nvarchar(max)varbinary(max)xml 列,则减少页中的行数会增加处理查询时必须读取的页数。减少每页上的行数会增加页的数量,优化器找不到可用的索引时可能必须扫描这些页。

也可以使用 sp_tableoption 禁用行外选项:

sp_tableoption N'MyTable', 'large value types out of row', 'OFF'

如果 large value types out of row 选项的值更改,现有的 varchar(max)nvarchar(max)varbinary(max)xml 的值不会立即转换。字符串的存储会随着字符串的更新而变化。任何插入表中的新值都将根据有效的表选项存储。

若要检查特定表的 large value types out of row 选项的值,请查询 sys.tables 目录视图的 large_value_types_out_of_row 列。如果表未启用 large value types out of row,则此列为 0;如果大值类型存储在行外,则此列为 1。

启用和禁用 text in row 选项

可以按照以下方式通过使用 sp_tableoption 为表启用 text in row 选项:

sp_tableoption N'MyTable', 'text in row', 'ON'

或者,可以为能够在数据行中存储的 textntextimage 字符串长度指定从 24 到 7,000 字节的最大限制:

sp_tableoption N'MyTable', 'text in row', '1000'

如果指定的是 ON 而不是一个特定的限制,则此限制的默认值为 256 字节。该默认值使您能够从使用 text in row 选项中获得最多的性能收益。虽然通常情况下,不应使该值的设置低于 72,但也不应将其设置的过高。该设置尤其适用于其中大多数语句都不引用 textntextimage 列的表,或其中有多个 textntextimage 列的表。

如果设置了较大的 text in row 限制,且行本身存储了许多字符串,则可以显著减少存储在每页上的数据行数。如果大多数引用表的语句都不访问 textntextimage 列,则减少页中的行数会增加处理查询时必须读取的页数。减少每页上的行会增加索引和页的大小,优化器找不到可用的索引时可能必须扫描这些索引和页。text in row 限制的默认值为 256,这足以确保小型字符串和根文本指针可以存储在行中,但不会使每页上的行减少太多以至影响性能。

对于具有表数据类型的变量和用户定义函数(返回)返回的表,text in row 选项自动设置为 256。不能更改该设置。

也可以使用 sp_tableoption 指定 OFF0 选项值来禁用此选项。

sp_tableoption N'MyTable', 'text in row', 'OFF'

若要检查特定表的 text in row 选项的值,请查询 sys.tables 目录视图的 text_in_row_limit 列。如果没有为表启用 text in row,则此列为 0;如果设置了行内限制,则此列为大于 0 的值。

使用 text in row 选项的效果

text in row 选项具有以下效果:

  • 启用 text in row 选项后,可以使用 TEXTPTR、READTEXT、UPDATETEXT 或 WRITETEXT 语句读取或修改表中存储的任何 textntextimage 值的部分。在 SELECT 语句中,可以读取整个 textntextimage 字符串,或使用 SUBSTRING 函数读取部分字符串。所有引用表的 INSERT 或 UPDATE 语句都必须指定完整的字符串,并且不能只修改 textntextimage 字符串的一部分。
  • 当第一次启用 text in row 选项时,现有的 textntextimage 字符串不会立即转换为行内字符串。仅当随后更新字符串时,这些字符串才转换成行内字符串。启用 text in row 选项后插入的任何 textntextimage 字符串都将作为行内字符串插入。
  • 禁用 text in row 选项可能是长时间运行的日志记录操作。表被锁定,并且所有行内 textntextimage 字符串都将转换为常规 textntextimage 字符串。运行命令所需的时间和已经修改的数据量,取决于必须从行内字符串转换为常规字符串的 textntextimage 字符串的数量。
  • text in row 选项不影响用于 SQL Native Client OLE DB 访问接口或 SQL Native Client ODBC 驱动程序的操作,而只会加快访问 textntextimage 数据的速度。
  • 启用 text in row 选项后,DB-Library 文本和图像函数(例如 dbreadtextdbwritetext)将无法在表上使用。

请参阅

概念

为列分配数据类型

其他资源

设计表

帮助和信息

获取 SQL Server 2005 帮助

更改历史记录

发布日期 历史记录

2006 年 12 月 12 日

新增内容:
  • 在“启用和禁用 text in row 选项”部分中,添加了以下段落:若要检查特定表的 large value types out of row 选项的值,请查询 sys.tables 目录视图的 large_value_types_out_of_row 列。