使用聚簇索引时,是否读取“行外”字段?


10

我知道VARCHAR(MAX)/NVARCHAR(MAX)使用列时会存储数据out of the row-数据行将具有指向另一个存储“大值”位置的指针。

我有以下问题:

  1. 是存储每个字段out of the row还是仅存储一个字段max
  2. 如果您使用clustered index表的读取整个记录,那么是否也读取了行外存储的字段?

VARCHAR(MAX)或NVARCHAR(MAX)被视为“大值类型”。大值类型通常存储在“行外”。这意味着...


2
最后引用的位是哪里来的?这是不正确的。
保罗·怀特9


3
原始MSDN线程(由Jacob Sebastian)中的全文是正确的。堆栈溢出“报价”损失了不少。您在上面引用的一小部分省略了所有重要的内容:)
保罗·怀特9

Answers:


13

我知道当使用VARCHAR(MAX)/NVARCHAR(MAX)列时,数据存储在行外。

实际上,这取决于large value types out of row选项的设置,可以使用进行设置sp_tableoption。从文档中

BOL提取物

默认MAX存储值在行,高达8000个字节,它们是否适合。除非您曾经使用sp_tableoption过默认值,否则您的MAX数据很可能会存储在行中。

也就是说,将MAX数据类型用于永远不会超过8000个字节的值是不明智的做法-而是使用非MAX类型。除此之外,处理MAX类型时的性能通常会大大降低,因为SQL Server必须准备好处理可能高达2GB的数据。

每个字段是存储在行之外还是仅存储在最大字段之外?

只有MAX那些。此外,如果将先前在行中的MAX列移出行,则仅影响该行中的该列。它在行中由指向行外LOB结构的指针替换。在某些情况下,非MAX列可能会移出行。

如果您正在使用表的聚集索引读取整个记录,那么行外存储的字段也会被读取吗?

扫描聚簇索引仅遍历行内数据。如果查询需要行外数据,则使用行内指针查找。


这始终是真的Scanning the clustered index traverses only in-row data.吗?例如,如果要显示NVARCHAR(MAX)字段值,那么仅使用in-row-data(如果值存储在行外)怎么可能?或者,当您使用聚簇索引(因为没有覆盖索引)而又不想work使用该NVARCHAR(MAX)字段时,SQL Server足够聪明,可以看到它并跳过对out-of-row数据的查找?
gotqn 2015年

感谢您的回答。所以,最后,如果你有两列- intnvarchar(max),你是只选择int列时,SQL-Server不浪费资源readout-of-row,因为它知道你不打算使用它的数据吗?
gotqn 2015年

非常感谢。这是非常好的。似乎,sp_tableoption当进行许多聚集索引查找/扫描时,使用ap 可以将表中不常用的所有东西都放到表外,以减小行的大小。
gotqn 2015年

3
@gotqn是的。关行是旧LOB类型的默认textntextimage。当然,您也可以将大类型存储在单独的表中。
保罗·怀特9

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.