我有一个查询应用程序扫描带有文本字段的整个表格。
查询执行了这么多次读取:
扫描计数 1,逻辑读取 170586,物理读取 3,预读读取 174716,lob 逻辑读取 7902578,lob 物理读取 8743,lob 预读读取 0。
如果我从选择中删除文本字段,则读取内容如下:
扫描计数 1,逻辑读取 170588,物理读取 0,预读读取 0,lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。
我不明白的是 lob 读取的工作原理:
如果我将逻辑读取与 lob 逻辑读取相加,我总共得到8.073.164 逻辑读取,如果我是正确的,大约是 64GB。
但是整个数据库只有7GB!
我可能遗漏了一些关于添加逻辑读取和 lob 逻辑读取的内容。
lob逻辑读取的数量实际上代表什么?
这是我的理论,
这些是逻辑读取,而不是物理读取。想象两行,这些行的 LOB 数据位于同一页面上(是的,页面可以跨行共享 LOB 数据)。
也许每个只读读取例如 100 个字节。每次读取仍然是逻辑读取。
此外,您说这些是文本数据类型,默认情况下不具有行内 LOB 数据。如果类型改为 varbinary(max),则默认设置是在行中包含 LOB 数据(只要它适合页面)。这可能会产生很大的不同,最好的方法取决于您是否经常需要 LOB 数据。您可以使用 sp_tableoption 重新配置它(对于这两种类型)。
我想我现在终于明白了。
SET STATISTICS IO ON
显示 8.073.164 lob 逻辑读取,这正是记录总数 * 2。这是因为 LOB 数据像普通页面一样存储在 B-Tree 结构中!因此,对于每一行,您执行 2 次额外的逻辑读取:一次用于根页面,另一次用于数据本身。
这是在我的具体情况下,因为表中最大的文本只有 24 个字节。
资源