我目前遇到了一个奇怪的问题,我对 SQL Server 的理解不太一致。我们使用 SQL 作为内部存储服务的文件存储,我们的数据库中有大约 50 万行数据。大多数文件 (86%) 的大小为 1mb 或以下,但即使在我们数据库的新副本上,我们只是为了测试而用数据填充表,当我们的 SQL Server 处于负载状态时,似乎存储在 BLOB 中的大量数据的行经常会导致超时。
我对 SQL Server 如何删除行的理解是,这是一个垃圾收集过程,即,该行被标记为幽灵,在将更改复制到事务日志后,该行随后被幽灵清理过程删除。这对我来说意味着,无论 blob 中的数据大小如何,行删除都应该接近即时。然而,在删除这些行时,我们肯定会遇到大量超时和惊人的低性能。
在我们的测试数据集中,超过 30mb 的文件会导致此问题。这是一种极端情况,我们并不经常遇到这种情况,尽管我们正在研究 SQL 文件流作为解决某些问题的方法,但我们仍在尝试缩小这些问题的来源范围。
我们正在事务内执行删除操作。我们还对元数据(例如文件大小统计信息)执行更新,但这些更新存在于与文件数据本身不同的单独表中。层次结构数据存储在包含文件信息的表中。
真的,归根结底,我们在删除方面所做的事情并不重要,我们只是找不到任何关于在包含大量 BLOB 数据的行上删除性能低下的参考资料。我们正在尝试确定这是否是一条值得探索的途径,或者是否一定是我们在删除方面的某个流程导致了这个问题。
是否有可能发生这种情况的情况?当许多删除操作同时发生时,数据库服务器是否经常会完全超时?如果存在此问题,是否有办法解决?
答案1
您能定义“超时”吗?命令需要多长时间才能完成?
SQL Server 将删除记录到事务日志中,然后当数据库检查点时,删除实际上已从数据文件中删除。运行删除时,页面将加载到内存中(如果它们尚未存在),并将删除写入事务日志。
当您从表中删除数据时,您想一次删除多少条记录?
答案2
是否有任何外键引用此表,或者表本身是否有任何外键?如果外键在列上没有索引,我见过删除性能下降,特别是当您有那么多行时。
也许可以尝试在执行删除时包含执行计划,看看是否有任何意外步骤(例如表扫描)发生。当您有活动的阻塞请求时,还要检查 sys.dm_exec_requests DMV,特别是 wait_type、wait_time 和 wait_resource 列。