数据仓库中有一个多步骤过程,它生成一个临时表,其中包含将为每个批处理的作业列表。通常这是大约5,000个工作岗位。在财务汇总结束时,我们可能会查看约500,000条已处理的记录。我注意到它的一小部分正在给我一个关于存储过程的这部分优化的早期超时:
DELETE jfs
FROM DataWarehouse.dbo.JobFinancialSummary jfs -- Financials table (> 3,000,000 records with indices)
INNER JOIN #JobList jl ON jfs.JobID = jl.JobID -- List of Jobs being processed (avg. of 5,000 records)
INNER JOIN FiscalPeriod fp ON fp.ID = jfs.FiscalPeriodID -- Month Reference Table (about 1,000 records)
WHERE fp.[Status] IN (1,2) -- Last 2 months
最令人困惑的是,这是存储过程中相对简单的部分,并且所有JOIN都在索引上。我唯一的问题是当优化器评估它时它是如何超时的。我的理解是,优化器为每个语句提供了自己的预算"但也许我错过了一些东西。为何超时?
答案 0 :(得分:2)
删除的原因有很多:
原因:
如果它将脱机删除,为了更快地删除,
然后捕获删除表的聚簇索引键
然后通过批量删除,您可以通过设置@@ rowCount或top batchsize我们可以更快地删除任意数量的记录。
DELETE TOP 50000 - 基于场景 FROM table1 在循环中
直接致电' CheckPoint'确保从事务日志中清除记录。还要确保您的恢复模式'是'简单'不是' Full' 如果它将在白天标记为在线删除,则作为软删除和在夜间作业中以非常小的批次运行删除
答案 1 :(得分:2)
隔离要删除的行/条目可能会更快,而不是在删除时加入。
这样的假设id
是您的主要关键/身份:
IF OBJECT_ID('tempdb..#tmp') IS NOT NULL DROP TABLE #tmp
SELECT jfs.ID
INTO #tmp
FROM DataWarehouse.dbo.JobFinancialSummary jfs -- Financials table (> 3,000,000 records with indices)
INNER JOIN FiscalPeriod fp ON fp.ID = jfs.FiscalPeriodID -- Month Reference Table (about 1,000 records)
WHERE fp.[Status] IN (1,2)
/* EXISTS IS FASTER THAN A JOIN, AVOIDS FANNING */
AND EXISTS (SELECT 1 FROM #JobList jl where jfs.JobID = jl.JobID) -- List of Jobs being processed (avg. of 5,000 records)
然后发出删除,例如:
DELETE TOP(1000) jfs
FROM DataWarehouse.dbo.JobFinancialSummary jfs
WHERE EXISTS (SELECT 1 FROM #tmp t WHERE jfs.ID=t.ID)
从那里开始,根据您要删除的行数,您可能希望在一夜之间批量删除 - 超过5000行的任何内容都会升级为表锁,并且是批量删除的主要候选者。
我写了一篇关于如何在这里完成大批量删除的相当受欢迎的答案: