【问题标题】:Performance tuning an update statement in SQL SERVER在 SQL SERVER 中调整更新语句的性能
【发布时间】:2015-07-27 05:36:54
【问题描述】:

我有 2 个更新语句。当两者一起执行时,从 SSIS 需要超过 12 小时。在执行此更新语句之前,此表上的所有索引均已禁用。我需要提高性能。我需要建议:

1) 第一次更新声明

Update Db1.table1
Set Db1.table1.col1 = Db2.table2.col1
from Db1.table1, Db2.table2
where Db1.table1.col2 = Db2.table2.col2

2) 第二次更新声明

update table1
set table1.col3 = 0
from table1
where table1.col3 is null

批量更新可以帮助提高第一次更新语句的性能吗? 我看到在 col3 上有一个默认值就足够了,而不是运行第二次更新。但我不确定它是否会影响插入查询。该表有很多数据。我不确定是否要更改表格以在表格包含大量数据的列上包含默认值。

请提供您对上述语句的性能调整的建议。另请注意,我对数据库没有适当的权限来验证执行计划。

【问题讨论】:

  • 为什么要删除索引? Db1.table1.col2 和 Db2.table2.col2 至少应该被索引。这将加快更新表所需的连接。最后,如果您无权分析您的查询,您应该将工作交给有权完成这项工作的人。
  • 在将数据插入表之前禁用索引以获得更好的性能。在插入和更新语句之后,我们启用索引。但是,目前这两个表中的这些列上既没有聚集索引,也没有非聚集索引。

标签: sql sql-server performance sql-server-2008 ssis


【解决方案1】:

首先,了解哪个更新需要更长时间会有所帮助。但是,在进行更新时,索引不一定是您的敌人。

第一次更新:

Update t1
    Set t1.col1 = t2.col2
    from Db1.table1 t1 join
         Db2.table2 t2
         on t1.col2 = t2.col2;

此更新确实需要db2.table2(col2) 上的索引。否则,它将需要进行嵌套循环连接。

第二次更新:

update table1
set table1.col3 = 0
from table1
where table1.col3 is null

有点棘手。您正在更新 where 子句中的列。我的感觉是,如果null 的值相对较少——最多只有几个百分点——那么table1(col3) 上的索引会有所帮助。如果许多列是空的,那么索引将不太有用。如果没有索引,这需要进行全表扫描,而且速度应该不会太慢。

您可能会发现批量更新此表有助于提高性能。

【讨论】:

  • 好答案。如果这消除了第二次更新的需要,我还建议保留 col3 的默认值。每次插入表时设置默认值的开销可以忽略不计。
【解决方案2】:

在运行第一条语句时,您应该:

  • 在 table1.col2 上有一个聚集索引
  • 在 table2.col2 上有一个聚集索引

请注意:每个表只能有 1 个聚集索引(因为该索引说明如何物理存储数据),并且它必须是在表上创建的第一个索引(反之亦然:您删除的最后一个)

正确的动作顺序:

  1. 创建表
  2. 创建聚集索引(是否唯一,无所谓)
  3. 创建非聚集索引

分别:

  1. 删除非聚集索引
  2. 删除聚集索引
  3. 删除表

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-05-26
    • 2017-08-29
    • 1970-01-01
    • 2021-12-03
    • 1970-01-01
    • 1970-01-01
    • 2021-04-11
    • 1970-01-01
    相关资源
    最近更新 更多