Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 2008 在SQL Server中更新或合并非常大的表_Sql Server 2008_Sql Update_Sql Merge - Fatal编程技术网

Sql server 2008 在SQL Server中更新或合并非常大的表

Sql server 2008 在SQL Server中更新或合并非常大的表,sql-server-2008,sql-update,sql-merge,Sql Server 2008,Sql Update,Sql Merge,我需要每天更新非常大(3亿条记录)和广泛的表1。更新的源数据位于另一个表UTABLE,它是TABLE1行的10%-25%,但很窄。两个表都有record\u id作为主键 目前,我正在使用以下方法重新创建表1: <!-- language: sql --> 1) SELECT (required columns) INTO TMP_TABLE1 FROM TABLE1 T join UTABLE U on T.record_id=U.record_id

我需要每天更新非常大(3亿条记录)和广泛的
表1
。更新的源数据位于另一个表
UTABLE
,它是
TABLE1
行的10%-25%,但很窄。两个表都有
record\u id
作为主键

目前,我正在使用以下方法重新创建
表1

<!-- language: sql -->
    1) SELECT (required columns) INTO TMP_TABLE1 
    FROM TABLE1 T join UTABLE U on T.record_id=U.record_id  
    2) DROP TABLE TABLE1  
    3) sp_rename 'TMP_TABLE1', 'TABLE1'
  • 我听说我可以使用ROWCOUNT执行批处理合并,但我认为对于一个300M行的表来说,这不够快

  • 是否有任何有帮助的SQL查询提示


  • 首先,我要找出你的瓶颈在哪里——你的CPU是固定的还是空闲的?换句话说,IO子系统是否能够正确处理负载

    重新创建完整的表需要大量的IO负载,更不用说临时存储两次表会占用大量空间

    你需要执行合并吗?从我看来,一个简单的更新就足够了。例如:

    UPDATE
        TABLE1
    SET
        ColumnX = UTABLE.ColumnX
        ...
    FROM
        TABLE1
    INNER JOIN
        UTABLE ON TABLE1.record_id = UTABLE.record_id
    
    您可以使用ROWCOUNT对更新进行批处理,但这不会加快执行速度,只会有助于减少总体锁定


    还有,你有什么样的索引?在更新之前禁用索引,然后在更新之后从头开始重建索引(只有非聚集的索引)可能会更快。

    事实上,我已经找到了针对此类查询的一般建议:使用SQL合并或更新的想法非常聪明,但当我们需要更新许多记录时(即75M)在一张又大又宽的桌子上(即240M

    查看下面查询的查询计划,我们可以说表1的
    表扫描
    和最终的
    合并
    占用了90%的时间

    MERGE TABLE1 as Target  
    USING UTABLE as source  
    ON Target.record_id = source.record_id   
    WHEN MATCHED AND (condition) THEN   
        UPDATE SET Target.columns=source.columns
    
    因此,为了使用合并,我们需要:

  • 减少需要更新的行数,并将此信息正确传递给SQL Server。这可以通过使
    UTABLE
    更小或指定额外的
    条件来实现,以缩小要合并的部分
  • 确保要合并的部分适合内存,否则查询运行速度会慢很多。减少两次
    TABLE1
    将我的实际查询时间从11小时减少到40分钟

  • 正如Mark提到的,您可以使用
    UPDATE
    语法和
    WHERE
    子句来缩小要合并的部分-这将给出相同的结果。另外,请避免索引
    表1
    ,因为这将导致在
    合并期间重建索引的额外工作。

    您好,谢谢您的回复,我没有索引,因为这只会减慢合并或更新查询。至于IO——基于平均磁盘队列计数器——磁盘非常繁忙,表1似乎不适合内存。现在我正在用CTE试验预过滤输入,只有在执行合并之后,我才会用结果回答我自己的问题。嗨@chris,查询计划非常简单:1个表扫描表1,2个表扫描表UTABLE,3个哈希连接,4个合并。第一步和最后一步占用了90%的时间。然而,我已经理解了如何解决我的问题——请看我自己的答案。
    MERGE TABLE1 as Target  
    USING UTABLE as source  
    ON Target.record_id = source.record_id   
    WHEN MATCHED AND (condition) THEN   
        UPDATE SET Target.columns=source.columns