由于性能问题,我需要更好地更新表这是我当前的表结构现在基于weekNum,表2的值需要更新。目前使用pivot来获取更新,任何其他备用解决方案。请帮忙
表1:
╔════════╦══════╦════════╦═══════╗
║ Row ID ║ Desc ║ WeekNum║ Amt ║
╠════════╬══════╬════════╬═══════╣
║ 1 ║ Total║ 01 ║ 25.00 ║
║ 2 ║ Total║ 02 ║ 55.00 ║
║ 3 ║ Total║ 04 ║ 78.00 ║
║ 4 ║ Total║ 06 ║ 99.00 ║
║ 5 ║ Total║ 07 ║ 54.00 ║
║ 6 ║ Total║ 09 ║ 58.00 ║
╚════════╩══════╩════════╩═══════╝
表2:
╔══╦═════╦══════╦══════╗═════╗═══════╗══════╗══════╗══════╗═════╗══════╗
║ID║ Desc║ 01 ║ 02 ║ 03 ║ 04 ║ 05 ║ 06 ║ 07 ║ 08 ║ 09 ║
╠══╬═════╬══════╬══════╣═════║═══════║══════║══════║══════║═════║═════ ║
║ 1║Total║25.00 ║55.00 ║NULL ║ 78.00 ║ NULL ║ 99.00║54.00 ║NULL ║58.00 ║
╚══╩═════╩══════╩══════╝═════╝═══════╝══════╝══════╝══════╝═════╝══════╝
答案 0 :(得分:0)
如果PIVOT
速度很慢,您可以将其分隔为9
包含在事务中的不同更新。您的基本查询将是:
UPDATE Table1
SET [01] = T2.[Amnt]
FROM Table1 T1
INNER JOIN Table2 T2
ON T1.[Desc] = T2.[Desc]
WHERE T2.[Week] = '01';
您将为每列执行此操作。如果您的真实示例包含更多不同的周数,则可以使用动态T-SQL语句来构建执行代码。它会更短,看起来更好。像这样:
DECLARE @DistitincWeeks TABLE
(
[Week] VARCHAR(8)
);
INSERT INTO @DistitincWeeks ([Week])
SELECT DISTINCT [Week]
FROM Table1;
DECLARE @DynamictSQLStatement NVARCHAR(MAX)
,@CurrentWeek VARCHAR(8);
WHILE(EXISTS(SELECT 1 FROM @DistitincWeeks))
BEGIN;
SELECT TOP (1) @CurrentWeek = [Week]
FROM @DistitincWeeks;
--
SET @DynamictSQLStatement = @DynamictSQLStatement +
'
UPDATE Table1
SET [' + @CurrentWeek + '] = T2.[Amnt]
FROM Table1 T1
INNER JOIN Table2 T2
ON T1.[Desc] = T2.[Desc]
WHERE T2.[Week] = ''' + @CurrentWeek +''';
';
--
DELETE FROM @DistitincWeeks
WHERE [Week] @CurrentWeek
END;
EXECUTE sp_executesql @DynamictSQLStatement;
或者,您可以在Table1
上创建一个插入后触发器,在数据发生更改时修改Table2
中的相应行。您可以使用上面代码的变体作为触发器主体。请确保您正在批量操作行,而不是循环或使用游标。
我不喜欢触发器,如果你有一个例行程序,存储过程或其他应用程序代码,我会建议你更新Table1
数据,只需更新Table2
中的数据。这对我来说更清楚,但你必须确保没有其他例程正在修改Table1
中的数据。
当Table2
中的数据被修改为每X小时或每天执行大量更新时,最好不断更新小批量Table1
。
如果以下更新也很慢:
UPDATE Table1
SET [01] = T2.[Amnt]
FROM Table1 T1
INNER JOIN Table2 T2
ON T1.[Desc] = T2.[Desc]
WHERE T2.[Week] = '01';
您应该检查表结构(列类型)本身和相应的索引。