我怎样才能 运行 这个 UPDATE 查询更快?
How can I run this UPDATE query faster?
UPDATE
WEB
SET
WEB.ID_D_SUPPORT = DIM.ID_D_SUPPORT
FROM
dbo.F_SUPPORT_WEB WEB
INNER JOIN
dbo.D_SUPPORT DIM
ON WEB.id_support = DIM.id_support
AND (WEB.date_creation BETWEEN DIM.Date_Deb_Valid AND DIM.Date_Fin_Valid)
我有下面的查询,table F_SUPPORT_WEB 中有 3 亿行要更新,我无法 运行 它,每次我都会遇到事务日志问题.
我认为 between 运算符是关键,但我不知道如何优化它。
有人可以帮助我吗?
您需要 运行 循环更新。当您尝试一次更新所有这些记录时,它必须将所有这些记录复制到事务日志以防出现错误,以便它可以回滚更改。如果您分批更新,您将不会 运行 进入该问题。见下文
SELECT 1 --Just to get a @@ROWCOUNT established
WHILE (@@ROWCOUNT > 0)
BEGIN
UPDATE TOP (5000000) WEB --Change this number to however many you want to update at a time
SET WEB.ID_D_SUPPORT = DIM.ID_D_SUPPORT
FROM dbo.F_SUPPORT_WEB WEB
INNER JOIN dbo.D_SUPPORT DIM ON WEB.id_support = DIM.id_support
AND (WEB.date_creation BETWEEN DIM.Date_Deb_Valid AND DIM.Date_Fin_Valid)
WHERE WEB.ID_D_SUPPORT != DIM.ID_D_SUPPORT --Don't update records that have already been updated, otherwise the loop will run forever
END
如果您的日志 table 驱动器不够大,无法支持单个事务,您需要将其分解为多个事务。我遇到了类似的问题并进行了测试,直到找到最佳位置(为我更新了 100,000 行)。一直循环直到完成所有记录。您可以通过简单地修改您的查询来做到这一点。
UPDATE WEB
SET WEB.ID_D_SUPPORT = DIM.ID_D_SUPPORT
FROM dbo.F_SUPPORT_WEB WEB
INNER JOIN dbo.D_SUPPORT DIM ON WEB.id_support = DIM.id_support
AND (WEB.date_creation BETWEEN DIM.Date_Deb_Valid AND DIM.Date_Fin_Valid)
WHERE WEB.ID_D_SUPPORT <> DIM.ID_D_SUPPORT
您可能希望首先添加 where 以查看您是否正在更新不必要的记录。
- 创建温度 table 用 dim.ids 变暗。
- 仅使用 id 批量插入临时 table 使用 DIM.Date_Deb_Valid AND DIM.Date_Fin_Valid.
的 DIM
- 在没有 (WEB.date_creation BETWEEN DIM.Date_Deb_Valid AND DIM.Date_Fin_Valid)
的情况下与临时 table 建立连接
UPDATE
WEB
SET
WEB.ID_D_SUPPORT = DIM.ID_D_SUPPORT
FROM
dbo.F_SUPPORT_WEB WEB
INNER JOIN
dbo.D_SUPPORT DIM
ON WEB.id_support = DIM.id_support
AND (WEB.date_creation BETWEEN DIM.Date_Deb_Valid AND DIM.Date_Fin_Valid)
我有下面的查询,table F_SUPPORT_WEB 中有 3 亿行要更新,我无法 运行 它,每次我都会遇到事务日志问题. 我认为 between 运算符是关键,但我不知道如何优化它。
有人可以帮助我吗?
您需要 运行 循环更新。当您尝试一次更新所有这些记录时,它必须将所有这些记录复制到事务日志以防出现错误,以便它可以回滚更改。如果您分批更新,您将不会 运行 进入该问题。见下文
SELECT 1 --Just to get a @@ROWCOUNT established
WHILE (@@ROWCOUNT > 0)
BEGIN
UPDATE TOP (5000000) WEB --Change this number to however many you want to update at a time
SET WEB.ID_D_SUPPORT = DIM.ID_D_SUPPORT
FROM dbo.F_SUPPORT_WEB WEB
INNER JOIN dbo.D_SUPPORT DIM ON WEB.id_support = DIM.id_support
AND (WEB.date_creation BETWEEN DIM.Date_Deb_Valid AND DIM.Date_Fin_Valid)
WHERE WEB.ID_D_SUPPORT != DIM.ID_D_SUPPORT --Don't update records that have already been updated, otherwise the loop will run forever
END
如果您的日志 table 驱动器不够大,无法支持单个事务,您需要将其分解为多个事务。我遇到了类似的问题并进行了测试,直到找到最佳位置(为我更新了 100,000 行)。一直循环直到完成所有记录。您可以通过简单地修改您的查询来做到这一点。
UPDATE WEB
SET WEB.ID_D_SUPPORT = DIM.ID_D_SUPPORT
FROM dbo.F_SUPPORT_WEB WEB
INNER JOIN dbo.D_SUPPORT DIM ON WEB.id_support = DIM.id_support
AND (WEB.date_creation BETWEEN DIM.Date_Deb_Valid AND DIM.Date_Fin_Valid)
WHERE WEB.ID_D_SUPPORT <> DIM.ID_D_SUPPORT
您可能希望首先添加 where 以查看您是否正在更新不必要的记录。
- 创建温度 table 用 dim.ids 变暗。
- 仅使用 id 批量插入临时 table 使用 DIM.Date_Deb_Valid AND DIM.Date_Fin_Valid. 的 DIM
- 在没有 (WEB.date_creation BETWEEN DIM.Date_Deb_Valid AND DIM.Date_Fin_Valid) 的情况下与临时 table 建立连接