我有一个表,我们刚刚启用了FileStreams。我们创建了一个新的varbinary列并将其设置为存储到文件流。然后我们将现有列中的所有内容复制到新列中,以便将文件数据推送到文件系统。
到目前为止一切顺利。
但是,我们无法在执行此操作时使数据库脱机(正常运行时间SLA),并且在更新语句运行之后但在我们重命名之前中有来自7400的2条记录列。我们目前有两列:FileData
和FileDataOld
。其中FileData
是绑定到文件流的那个。
平均文件大小略大于2MB。所以,我决定运行一个非常简单的select语句来查找未执行的记录:
select DocumentId, FileName
from docslist
where FileData is null
当我运行此查询时,CPU飙升至80%并在那里坐了很长时间。最终我在2分钟后杀了选择因为那只是疯了。
如果我运行的话:
select DocumentId, FileName from docslist
它几乎立即返回。
然而,一旦我尝试查询FileData
或FileDataOld
为空的地方,它就会旋转到永远的土地上。
当使用资源监视器,并且我查询'FileData为null'时,我可以看到它从文件系统中的每个文档中提取每个字节。这很奇怪;你认为信息将存储在表格本身中。
如果我查询FileDataOld is null
,看起来它正在尝试将整个表(16GB)加载到内存中。
我该如何改进?我只需要获取update语句之后发生的2条记录并强制移动这些文档。
答案 0 :(得分:1)
你不能这样做:
select DocumentId, FileName from docslist WHERE DATALENGTH(FileData)>0
在mdsn上它说:
DATALENGTH对varchar,varbinary,text,image特别有用, nvarchar和ntext数据类型,因为这些数据类型可以存储 可变长度数据。
NULL的DATALENGTH为NULL。
参考here