Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/75.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL Server文件流-删除";“速度”;_Sql_Sql Server_Filestream - Fatal编程技术网

SQL Server文件流-删除";“速度”;

SQL Server文件流-删除";“速度”;,sql,sql-server,filestream,Sql,Sql Server,Filestream,我第一次使用filestream数据类型(SQL Server 2008),在执行一些快速插入/删除操作时遇到了问题。基本上,从文件系统中实际删除文件的速度要比插入/删除速度慢得多,即使我手动调用垃圾收集器(据我所知,检查点应该调用垃圾收集器) 下面的代码说明了这个问题-执行大约需要30秒,但要从文件系统中删除最后一个文件(当我查找C:\FSTest\Files文件夹时),您必须等待几分钟 有没有办法加快垃圾收集器的速度?(它似乎大约每10秒删除20个文件——这让我相信,如果我每秒存储/删除超过

我第一次使用filestream数据类型(SQL Server 2008),在执行一些快速插入/删除操作时遇到了问题。基本上,从文件系统中实际删除文件的速度要比插入/删除速度慢得多,即使我手动调用垃圾收集器(据我所知,检查点应该调用垃圾收集器)

下面的代码说明了这个问题-执行大约需要30秒,但要从文件系统中删除最后一个文件(当我查找C:\FSTest\Files文件夹时),您必须等待几分钟

有没有办法加快垃圾收集器的速度?(它似乎大约每10秒删除20个文件——这让我相信,如果我每秒存储/删除超过2条记录,我最终会填满硬盘)

多谢各位

CREATE DATABASE FSTest ON PRIMARY
    (NAME = FSTest_data, FILENAME = N'C:\FSTest\FSTest_data.mdf'),
FILEGROUP FSTestFileGroup CONTAINS FILESTREAM
    (NAME = FSTestFiles,FILENAME = N'C:\FSTest\Files')
LOG ON 
    (NAME = 'FSTest_log', FILENAME = N'C:\FSTest\FSTest_log.ldf');
GO

USE FSTest;
GO

CREATE TABLE FSTest (
    Guid UNIQUEIDENTIFIER ROWGUIDCOL NOT NULL UNIQUE DEFAULT NEWSEQUENTIALID(),
    Name VARCHAR (25),
    Data VARBINARY(MAX) FILESTREAM);
GO

ALTER DATABASE FSTest SET RECOVERY SIMPLE;
GO

SET NOCOUNT ON
DECLARE @test int
SET @test=0
WHILE @test<1000 BEGIN
    INSERT INTO FSTest(Name,Data) VALUES('test',CAST('abc' AS VARBINARY(MAX)))
    DELETE FROM FSTest WHERE Name='test'
    CHECKPOINT
    SET @test = @test+1
END
在主服务器上创建数据库FSTest
(NAME=FSTest\u data,FILENAME=N'C:\FSTest\FSTest\u data.mdf'),
文件组FSTestFileGroup包含文件流
(NAME=FSTestFiles,FILENAME=N'C:\FSTest\Files')
登录
(名称='FSTest_log',文件名=N'C:\FSTest\FSTest_log.ldf');
去
使用FST测试;
去
创建表FSTest(
Guid UNIQUEIDENTIFIER ROWGUIDCOL NOT NULL唯一默认NEWSEQUENTIALID(),
名称VARCHAR(25),
数据变量二进制(最大)文件流);
去
改变数据库测试集恢复简单;
去
不计较
声明@testint
设置@test=0

而@test事情比简单的检查点要复杂一些。当包含有关文件创建的日志记录的最后一个VLF处于非活动状态时,可以删除该文件。请参阅。

正如雷姆斯所说,如果您使用的是完全恢复模型,那么事情就复杂了。但即使在简单恢复模型下,您也需要记住检查点调用垃圾收集器(GC),但它不能保证GC会在一次传递中删除所有文件。GC目前对在一次调用中可以执行的操作数量有限制。此外,文件是使用FILE_DELETE_ON_CLOSE选项删除的,因此,只要文件有打开的句柄,您仍然可以看到它,即使GC可能已经删除了它。此类打开的句柄可能由防病毒程序或其他文件系统筛选器驱动程序持有

最后,除非您的磁盘空间真的用完了,否则我不会太担心过时的文件——它们最终会作为自动数据库检查点的一部分被删除。我相信(虽然这里的关键字是“相信”),即使它的“启动时间”可能很慢,但如果您稳定地运行测试更长的时间(分钟?),GC仍会继续物理删除文件

如果您关心性能,那么将filestream容器保留在系统驱动器上可能不是一个好主意。有关文件流性能提示,请参阅。

经过进一步研究(并感谢Paul Randal的博客-关于文件流和垃圾收集的大量非常详细的信息),一旦删除行并执行检查点,文件将放入系统表(墓碑表),然后每10秒执行一次进程(重影清理)运行并从该表中删除一些项(确切地说是20项)。因此,基本上我们被限制在2次删除/秒,似乎没有办法(目前)改变这种行为

由于我有一个持续的每秒4次删除,我需要找到一个替代文件流的方法


感谢大家的投入。

实际上,在回答这个问题之前,我偶然发现了这篇文章,并了解到在“简单”恢复模型中,我只需要触发检查点就可以进行垃圾收集。也就是说,我对VLF之类的东西知之甚少,可能遗漏了某个地方的一条重要信息。Remus,你链接的博客文章并不准确。垃圾收集与VLF无关。它只需要一个检查点-日志备份-等待几秒钟-检查点-日志备份序列,这可能也会导致VLF切换,但这不是GC想要的。我想你是对的,我将尝试更持久的负载,看看它如何反应。至于“对一次调用中可能进行的操作数量的限制”,我们知道这个限制吗,有没有办法提高这个限制?我只是希望我以后不会撞到墙。我尝试了持续的方案,运行40分钟后,同样的问题是可观察到的文件数大约为5000:文件创建速度比删除速度快。(我用观察结果更新了主要帖子)。你能试试真实大小的文件吗?对于小于1兆字节的内容,通常不建议使用filestream。
SET NOCOUNT ON
DECLARE @test int
SET @test=0
WHILE @test<100000 BEGIN
    INSERT INTO FSTest(Name,Data) VALUES('test',CAST('abc' AS VARBINARY(MAX)))
    DELETE FROM FSTest WHERE Name='test'
    WAITFOR DELAY '00:00:00:200'
    CHECKPOINT
    SET @test = @test+1
END