使用 varbinary(max) 列缓慢删除

Jam*_*Orr 5 performance sql-server delete azure-sql-database query-performance

我有两个表,它们在处理之前临时保存来自 Web 应用程序的上传数据。这是在 Azure SQL 数据库上运行的。

上传文件

Id uniqueidentifier
CustomerId uniqueidentifier
FileName nvarchar(MAX) NULL
UploadDate datetime
UploadedBy nvarchar(MAX) NULL
Run Code Online (Sandbox Code Playgroud)

上传文件块

Id uniqueidentifier
Data varbinary(MAX) NULL
UploadFileId uniqueidentifier
[Index] int
Run Code Online (Sandbox Code Playgroud)

UploadFile有一个外键,级联删除到UploadFileChunk. UploadFileChunk在 上有一个非聚集索引UploadFileId。我一直在上传每个 1MB 的块。

插入和读取这些数据工作得很好,但是UploadFile在处理完数据后删除记录真的很慢。在 S0 10 DTU 测试 Azure 环境中,删除 12 条记录和大约 500 个子块总共需要 38 分钟(仅举个例子 - 它在我们的更高功率的生产环境和快速的本地机器上也表现不佳。)

我如何使它快速?

这里一个索引UploadFileChunk.FileUploadId。这是执行计划

我多次运行以下查询(来自在 SQL Azure 中查找阻塞查询),而慢速删除是在执行中,并且没有返回任何结果:

SELECT TOP 10
    r.session_id,
    r.plan_handle,
    r.sql_handle,
    r.request_id,
    r.start_time,
    r.status,
    r.command,
    r.database_id,
    r.user_id,
    r.wait_type,
    r.wait_time,
    r.last_wait_type,
    r.wait_resource,
    r.total_elapsed_time,
    r.cpu_time,
    r.transaction_isolation_level,
    r.row_count,
    st.text
FROM sys.dm_exec_requests r
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) AS st
WHERE
    r.blocking_session_id = 0
    AND r.session_id IN 
    (
        SELECT DISTINCT (blocking_session_id) FROM sys.dm_exec_requests)
GROUP BY
    r.session_id,
    r.plan_handle,
    r.sql_handle,
    r.request_id,
    r.start_time,
    r.status,
    r.command,
    r.database_id,
    r.user_id,
    r.wait_type,
    r.wait_time,
    r.last_wait_type,
    r.wait_resource,
    r.total_elapsed_time,
    r.cpu_time,
    r.transaction_isolation_level,
    r.row_count,
    st.text
ORDER BY
    r.total_elapsed_time DESC;
Run Code Online (Sandbox Code Playgroud)

截断可能比删除更快,但这两个表包含多个文件的数据,我必须能够一次删除一个。该nvarchar(max)列大概可能是别的东西,这正是实体框架基于我们的领域类生成的。你认为这对解决这个问题有帮助吗?

我确认直接从中删除记录FileUploadChunks同样慢。在我的超慢示例(S0 10 DTU)中,每删除行大约需要 1 秒。

Jam*_*Orr 2

我刚刚结束了与微软金牌合作伙伴支持一周的来回。他们已经确认这种情况没有任何好转,并且这些缓慢的删除是 SQL Azure/2016 的正常行为。