我已将超过4亿条记录导入虚拟维度表。我需要获取现有的事实表并加入虚拟维度以对事实表执行更新。为了避免填写事务日志,有人建议我执行循环来更新这些记录,而不是一次更新数亿条记录。我有研究循环并使用等待和延迟进行研究,但我不确定编写逻辑的最佳方法。
以下是我需要执行的示例更新:
Update f
set f.value_key = r.value_key
FROM [dbo].[FACT_Table] f
INNER JOIN dbo.dummy_table r ON f.some_key = r.some_Key
and r.calendar_key = f.calendar_key
WHERE f.date_Key > 20130101
AND f.date_key < 20141201
AND f.diff_key = 17
如果有人对最佳写作方式有任何建议,我会非常感激。
答案 0 :(得分:0)
为了避免填写事务日志,您可以在开发机器上将恢复模型设置为SIMPLE - 这样可以防止在完成日志备份时事务日志膨胀。
ALTER DATABASE MyDB SET RECOVERY SIMPLE;
如果您想更快地执行更新,请使用提示即。,(tablock)。
答案 1 :(得分:0)
请不要做以前的人建议的事情,除非你真的明白还会发生什么。最重要的结果是您失去了进行时间点恢复的能力。如果您每晚进行完全恢复并且每小时(或每15分钟)恢复一次事务日志,则切换到简单的恢复模型会破坏链,您只能恢复到上次完全恢复时间。
如果你这样做,你必须这样做(切换到简单)切换回完全并进行完整备份,然后切换回按计划进行日志备份。当前一个人建议就像驾驶没有保险杠,以节省汽车重量。听起来很棒,直到你碰到了什么。
答案 2 :(得分:0)
-- Run this section of code one time to create a global queue containing only the columns needed to identify a unique row to process. Update the SELECT statement as necessary.
IF OBJECT_ID('Tempdb.dbo.##GlobalQueue') IS NOT NULL
DROP TABLE ##GlobalQueue
SELECT diff_key, date_key INTO ##GlobalQueue FROM [dbo].[FACT_Table] f
INNER JOIN dbo.dummy_table r ON f.some_key = r.some_Key
and r.calendar_key = f.calendar_key
WHERE f.date_Key > 20130101
AND f.date_key < 20141201
AND f.diff_key = 17
-- Copy/paste the SQL below to run from multiple sessions/clients if you want to process things faster than the single session. Start with 1 session and move up from there as needed to ramp up processing load.
WHILE 1 = 1
BEGIN
DELETE TOP ( 10000 ) --Feel free to update to a higher number if desired depending on how big of a 'bite' you want it to take each time.
##Queue WITH ( READPAST )
OUTPUT Deleted.*
INTO #RowsToProcess
IF @@ROWCOUNT > 0
BEGIN
Update f
set f.value_key = r.value_key
FROM [dbo].[FACT_Table] f
INNER JOIN dbo.dummy_table r ON f.some_key = r.some_Key
INNER JOIN #RowsToProcess RTP ON r.some_key = RTP.diff_key
and f.calendar_key = RTP.calendar_key
DELETE FROM #RowsToProcess
--WAITFOR DELAY '00:01' --(Commented out 1 minute delay as running multiple sessions to process the records eliminates the need for that). Here just for demonstration purposes as it may be useful in other situations.
END
ELSE
BREAK
END
答案 3 :(得分:0)
使用top和&lt;&gt;
在更新中,您必须使用top(#)
while 1 = 1
begin
update top (100) [test].[dbo].[Table_1]
set lname = 'bname'
where lname <> 'bname'
if @@ROWCOUNT = 0 break
end
while 1 = 1
begin
Update top (100000) f
set f.value_key = r.value_key
FROM [dbo].[FACT_Table] f
INNER JOIN dbo.dummy_table r
ON f.some_key = r.some_Key
and r.calendar_key = f.calendar_key
AND f.date_Key > 20130101
AND f.date_key < 20141201
AND f.diff_key = 17
AND f.value_key <> r.value_key
if @@ROWCOUNT = 0 break
end