使用子查询的SQL更新缓慢

时间:2018-08-23 17:18:58

标签: sql sql-server

大家好……想知道是否有人可以帮助我解决这个问题。

我正在运行一个查询以根据销售线更新产品类别,并且需要回退几百万条记录,因此我在下面编写了查询以针对特定的订单ID运行

DECLARE @ID INT

SET @ID = 659483

UPDATE [TradeSpace].[TradeSpace].[dbo].[SalesLine] 
   SET [ProductCategory] = [curSync].[pc_Cat] 
  FROM (SELECT [SC_ID], 
               [pc_cat] 
          FROM [MW_MereSys].[dbo].[MWSLines] 
         INNER 
          JOIN [MW_MereSys].[dbo].[MWProductCats] 
            ON [MWSLines].[pc_catref] = [MWProductCats].[pc_catref]
         WHERE [sh_id] = @ID
       ) AS [curSync]
 WHERE [SalesLine].[slID] =  [curSync].[sc_id] 
   AND [salesline].[soid] = @ID 

子SELECT的运行时间不到一秒钟,但更新尚未完成(最多保留了一个小时)。存在[slID]和[soid]的索引。.手动更新一行不到一秒钟,但是像这样运行(十行)却非常慢。

请问有人有任何线索。我已经写过很多这样的查询,但是从来没有遇到过问题……陷入困境:(

2 个答案:

答案 0 :(得分:0)

您的查询未进行任何更改:

UPDATE s SET 
    ProductCategory = curSync.pc_Cat
FROM TradeSpace.TradeSpace.dbo.SalesLine s
INNER JOIN
  (
    SELECT [SC_ID], [pc_cat] 
    FROM [MW_MereSys].[dbo].[MWSLines]  l
    INNER JOIN [MW_MereSys].[dbo].[MWProductCats] c ON l.[pc_catref] = c.[pc_catref]
    WHERE [sh_id] = @ID
  ) AS [curSync]
  on s.[slID] =  [curSync].[sc_id]
WHERE s.[soid] = @ID

您确定这里的一切正确吗? SalesLine中的那一行总是只与子查询中的一行匹配?

然后尝试一下。如果不是这样,将失败。原始查询会在相同情况下以不同的值默默更新同一行。

UPDATE s SET 
    ProductCategory = (
            SELECT [pc_cat] 
            FROM [MW_MereSys].[dbo].[MWSLines]  l
            INNER JOIN [MW_MereSys].[dbo].[MWProductCats] c ON l.[pc_catref] = c.[pc_catref]
            WHERE [sh_id] = @ID
              AND [sc_id] = s.[slID]
          )
FROM TradeSpace.TradeSpace.dbo.SalesLine s
WHERE s.[soid] = @ID

并且请检查估计的执行计划。它会命中索引吗?

答案 1 :(得分:0)

我们需要其他细节,例如我在评论中提到的

由于将更新表与Sub查询结果结合在一起时,由于基数估计很高,因此更新速度很慢。

可能是因为连接错误和谓词所在。

您可以将子查询结果放入#Temp表中并尝试。也可以在#temp表中创建相同的索引。

DECLARE @ID INT

SET @ID = 659483

create #temp table([SC_ID] int,[pc_cat] int)

insert into #temp 
SELECT [SC_ID], 
               [pc_cat] 
          FROM [MW_MereSys].[dbo].[MWSLines] 
         INNER JOIN [MW_MereSys].[dbo].[MWProductCats] 
            ON [MWSLines].[pc_catref] = [MWProductCats].[pc_catref]
         WHERE [sh_id] = @ID




UPDATE SalesLine 
   SET [ProductCategory] = [curSync].[pc_Cat] 
  FROM [TradeSpace].[TradeSpace].[dbo].[SalesLine] as SalesLine
inner join #temp  AS [curSync]
 WHERE [SalesLine].[slID] =  [curSync].[sc_id] 
   AND [salesline].[soid] = @ID 

drop table #temp