【问题标题】:Multiple Update statements running slow in SQL Stored procedureSQL 存储过程中多个更新语句运行缓慢
【发布时间】:2014-10-14 01:00:21
【问题描述】:

请参考以下 SQL 命令,它是存储过程的一部分。存储过程创建一个名为#TREPORT 的临时表,然后我对 SODATE 列执行以下多次更新。

临时表 (#TREPORT) 有大约 100 万条记录,以下语句使性能变慢。我该如何进一步改进它?

@SDATE 和@EDATE 是参数,分别是开始日期和结束日期。

提前致谢。

   UPDATE #TREPORT SET 
          SODATE  = '1900-01-01 00:00:00.000' where #TREPORT.SODATE is NULL

   UPDATE #TREPORT SET 
          SODATE  = (SELECT TOP 1 docdate from SO200 
          where SO200.NUMBORIG = #TREPORT.SOPNr 
          AND SO200.SOTYPE = '3' 
    --         AND 
    --DOCDATE is not null and DOCDATE >= '' +CONVERT(varchar(10),@SDATE,101) +''
    --         and DOCDATE <= '' +CONVERT(varchar(10),@EDATE,101) +''
      ) 
          where #TREPORT.SODATE = '1900-01-01 00:00:00.000' or #TREPORT.SODATE is NULL

   UPDATE #TREPORT SET 
          SODATE  = (SELECT TOP 1 docdate from SO100 
          where SO100.NUMBORIG = #TREPORT.SOPNr 
          AND SO100.SOTYPE = '3' 
    --         AND 
    --DOCDATE is not null and DOCDATE >= '' +CONVERT(varchar(10),@SDATE,101) +''
    --         and DOCDATE is not null and DOCDATE <= '' +CONVERT(varchar(10),@EDATE,101) +''
      ) 
      where #TREPORT.SODATE = '1900-01-01 00:00:00.000'  or #TREPORT.SODATE is NULL

   UPDATE #TREPORT SET 
          RowValue = 'C' where 
      (#TREPORT.SODATE < '' +CONVERT(varchar(10),@SDATE,101) +''
          or #TREPORT.SODATE > '' +CONVERT(varchar(10),@EDATE,101) +'')

   UPDATE #TREPORT SET 
          RowValue = 'D' where #TREPORT.SODATE  = '1900-01-01 00:00:00.000' 
          or #TREPORT.SODATE is NULL

【问题讨论】:

    标签: performance sql-server-2008 tsql stored-procedures sql-update


    【解决方案1】:

    大型更新最好分批执行。在此处查看解决方案:

    http://www.sqlusa.com/bestpractices/largeupdate/

    至于合并您的更新,您的第一次更新完全是多余的,因为您将 NULL 替换为默认值,而其他更新替换“NULL 或 {默认值}”,因此您可以跳过第一个完全。

    其他 4 个更新可以通过 CASE 语句合并为一个。

    UPDATE #TREPORT SET SODATE=CASE
      WHEN EXISTS(SELECT * from SO200 where SO200.NUMBORIG = #TREPORT.SOPNr AND SO200.SOTYPE = '3')
        THEN (SELECT TOP 1 docdate from SO200 
              where SO200.NUMBORIG = #TREPORT.SOPNr 
              AND SO200.SOTYPE = '3')
      WHEN EXISTS(SELECT * from SO100 where SO100.NUMBORIG = #TREPORT.SOPNr AND SO100.SOTYPE = '3')
        THEN (SELECT TOP 1 docdate from SO100 
              where SO100.NUMBORIG = #TREPORT.SOPNr 
              AND SO100.SOTYPE = '3')
      ELSE '1900-01-01 00:00:00.000' 
    END
    ,  RowValue=CASE
      WHEN       (#TREPORT.SODATE < '' +CONVERT(varchar(10),@SDATE,101) +''
              or #TREPORT.SODATE > '' +CONVERT(varchar(10),@EDATE,101) +'')
        THEN 'C'
      ELSE 'D'
    END
    where #TREPORT.SODATE = '1900-01-01 00:00:00.000' or #TREPORT.SODATE is NULL
    

    【讨论】:

    • 谢谢,但我想知道是否可以将这些多个更新合并为 1 个或更小的 UPDATE 命令。我有关于 SODATE 字段的更新声明。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多