nvarchar(max)和表扫描

本文探讨了一个有趣的数据库现象:在30G数据的表中,通过简单SQL查询特定记录仅耗时0.3秒的原因。文章详细分析了执行计划及IO统计,并揭示了nvarchar(max)类型字段如何影响数据存储与检索效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

刚才有同事问我一个他觉得很奇怪的现象,一个表有30多G的数据,他使用一句简单的SQL语句查询表中的一行数据,执行计划显示数据库使用了聚集索引扫描,但执行时间只有0.3秒,为什么扫描30G的数据只需要0.3秒?

下面来看一下查询

set statistics io on
select * from EI_InterfaceContentLogs where TransId='EI_20140410133840630'
<p>(1 行受影响)
表 'EI_InterfaceContentLogs'。扫描计数 5,逻辑读取 54441 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'Worktable'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。</p>

看IO统计来看,只做了54441次逻辑读取,大概只读取了400多M的数据,感觉是有点怪怪的,再看一下表结构:



注意到这里OutPut字段是nvarchar(max)类型,原因就和清楚了,nvarchar(max)数据默认是直接存储在数据行中(最大限制值为 8000 个字节,只要记录中可以容纳该值)。如果记录中容纳不下该值,则指针存储在行内,其余内容存储在 LOB 存储空间内,所以这里只需要扫描聚集索引的叶级页,找到对应的行后,再根据指针到LOB存储空间中去找到Output这一列的值。

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值