【问题标题】:minimize time when updating table with left join使用左连接更新表时最小化时间
【发布时间】:2013-06-23 08:07:05
【问题描述】:

我有 2 张桌子,例如:

-table1: id_1, id_2, id_3, ref_id (id_1, id_2 is pk)
-table2: ref_id, id_4

我希望 id_3 字段应该等于 table2 的 id_4(ref_id 是主键) table1 大约有 600 万条记录,table2 大约有 2700 条记录。

我写了一个类似的sql:

update table1
set id_3 = b.id_3
from table1 
left join table2 b on id_1= b.ref_id

通过使用 SQL Server,查询需要花费 16 小时左右的时间,但仍然没有响应。如何减少查询时间?

【问题讨论】:

  • 您在哪些列上有索引?可能是在更新大量索引数据之前删除一些索引的选项,然后在之后重建索引 - 如果可能的话,当然是(如果您不需要列值的强制唯一性或其他东西)。
  • 我不认为这花了这么长时间,所以不存在索引。

标签: sql-server performance sql-update


【解决方案1】:

听起来确实花了很长时间,但缺乏索引可能是造成这种情况的原因。如果没有索引,数据库基本上必须为 6M 记录表中的每条记录遍历 2700 条记录。

首先在ref_id 上添加一个索引(假设主键不是索引),然后在id_1 上添加一个索引。

为了使事情更容易监控(就进度而言),只需循环遍历表 2 中的 2700 条记录,然后对每条记录(或每 10、100 条等)进行更新,以便您可以部分更新并查看如何远了。

另外,为了确保您不会做任何无用的事情,我建议您添加and table1.id_3 <> table2.id_3

【讨论】:

    【解决方案2】:

    无论如何更新 600 万行表中的每一行都可能会很慢。

    获得更新每一行的最大速度基准的一种方法是对查询进行计时:

    update table1
    set id_3 = 100
    

    另外,您是否需要更新 table1 中与 table2 中没有匹配行的行?在这种情况下,将左外连接切换为内连接将大大提高性能。

    【讨论】:

      【解决方案3】:

      要回答这个问题,我们确实需要知道两个表上的聚集索引是什么。我可以对聚集索引提出建议,以使这个特定的查询更快,但是,在选择聚集索引时应该考虑其他因素。

      考虑到这一点,看看这些索引是否有帮助:

      table1: (id_1, id_2) 上的唯一聚集索引 表 2:(ref_id)上的唯一聚集索引

      如果您的 PK 尚未集群,则基本上使它们成为集群。

      另一件重要的事情是,当您运行此更新时,表是否会看到其他流量。如果是这样,那么长时间运行可能是由于阻塞。在这种情况下,您应该考虑批处理,即一次只更新一小部分,而不是在单个语句中全部更新。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-03-09
        • 2018-04-27
        • 2021-05-12
        • 2011-11-27
        • 2020-09-21
        • 1970-01-01
        • 2015-01-13
        • 2021-05-20
        相关资源
        最近更新 更多