我需要从一个表中插入130万条记录到另一个表中,并且需要很长时间(超过13分钟)。经过一番研究,我发现,这是更好地做分批这种操作,所以我放在一起这样的事情(实际查询比较复杂,这里简化为简洁明快):TSQL批插入 - 数学不起作用
DECLARE @key INT; SET @key = 0;
CREATE TABLE #CURRENT_KEYS(KEY INT)
WHILE 1=1
BEGIN
-- Getting subset of keys
INSERT INTO #CURRENT_KEYS(KEY)
SELECT TOP 100000 KEY FROM #ALL_KEYS WHERE KEY > @key
IF @@ROWCOUNT = 0 BREAK
-- Main Insert
INSERT INTO #RESULT(KEY, VALUE)
SELECT MAIN_TABLE.KEY, MAIN_TABLE.VALUE
FROM MAIN_TABLE INNER_JOIN #CURRENT_KEYS
ON MAIN_TABLE.KEY = #CURRENT_KEYS.KEY
SELECT @key = MAX(KEY) FROM #CURRENT_KEYS
TRUNCATE TABLE #CURRENT_KEYS
END
我已经索引列表#ALL_KEYS表中有130万个密钥,所以这里的想法是在循环中为JOIN和INSERT创建更小的子集。上述循环执行13次(批量中有1,300,000条记录/ 100,000条记录)。如果我在一次迭代之后休息一下 - 执行时间为9秒。我假设总执行时间为9 * 13秒,但是13分钟一样!
任何想法为什么?
注意:而不是临时表#CURRENT_KEYS,我试图使用CTE,但结果相同。
UPDATE一些等待统计。
我在这个过程中显示PAGEIOLATCH_SH
有时候PREEMPTIVE_OS_WRITEFILEGATHER
等待统计有时会超过500毫秒,但通常是< 100Ms。此外SP_WHO在查询期间将用户显示为suspended
。
你测量任何等待统计数据,看看正在13分钟?可能是日志的自动增长,tempdb数据文件阻塞,谁知道? –
@AaronBertrand不知道该怎么做,我不是DBA,在优化方面也没什么经验 –
您[可能会发现这是一个有用的阅读](http://www.sqlperformance.com/2013/03/io-subsystem /块状删除)。或者你有聘请谁有优化经验的人。 :-)你是否尝试使用循环内的事务? –