SQL UPDATE表现不佳

时间:2011-06-23 23:16:19

标签: sql sql-server tsql

我的数据库表包含以下列: A1,A2,A3,A4,A5,A6

每当遇到空列时,我都必须更新这些记录并移动值。目的是在具有从左开始的值的列之间不具有空值。例如,如果:

A1 = NULL , A2 = 1 , A3 = 4, A4 = 5, A5 = 9, A6 = 8

我必须将值左移,以便结果为:

A1 = 1, A2 = 4 , A3 = 5, A4 = 9, A5 = 8, A6 = NULL

到目前为止,我已经提出了以下查询,但速度很慢。如果您可以调整查询以使其更快,请告诉我。还有一件事,如果我在c#中这样做怎么办?如果我在那里遍历Datarows并更新每一行,它会更快吗?

UPDATE myTable SET
    A5 = A6,
    A6 = NULL
WHERE (A5 IS NULL) AND (NOT A6 IS NULL)

UPDATE myTable SET
    A4 = A5,
    A5 = A6
WHERE (A4 IS NULL) AND (NOT A5 IS NULL)

UPDATE myTable SET
    A3 = A4,
    A4 = A5,
    A5 = A6
WHERE (A3 IS NULL) AND (NOT A4 IS NULL)

UPDATE myTable SET
    A2 = A3,
    A3 = A4,
    A4 = A5,
    A5 = A6
WHERE (A2 IS NULL) AND (NOT A3 IS NULL)

UPDATE myTable SET
    A1 = A2,
    A2 = A3,
    A3 = A4,
    A4 = A5,
    A5 = A6
WHERE (A1 IS NULL) AND (NOT A2 IS NULL)

4 个答案:

答案 0 :(得分:2)

鉴于[anything] + NULL + [anything]为空,如何;

declare @t table(A1 int, A2 int, A3 int, A4 int, A5 int, A6 int)
insert @t values 
   (NULL, 2 , 3, 4, 5, 6),
   (1, NULL, 3, 4, 5, 6),
   (1, 2, NULL, 4, 5, 6),
   (1, 2, 3, NULL, 5, 6),
   (1, 2, 3, 4, NULL, 6),
   (1, 2, 3, 4, 5, NULL),
   (1, 2, 3, 4, 5, 6)

update @t
  set A1 = coalesce(A1, A2),
  A2 = case when A1 + A2                is null then A3 else A2 end,
  A3 = case when A1 + A2 + A3           is null then A4 else A3 end,
  A4 = case when A1 + A2 + A3 + A4      is null then A5 else A4 end,
  A5 = case when A1 + A2 + A3 + A4 + A5 is null then A6 else A5 end,
  A6 = case when A1 + A2 + A3 + A4 + A5 is null then null else A6 end
from @t

select * from @t


A1  A2  A3  A4  A5  A6
2   3   4   5   6   NULL
1   3   4   5   6   NULL
1   2   4   5   6   NULL
1   2   3   5   6   NULL
1   2   3   4   6   NULL
1   2   3   4   5   NULL
1   2   3   4   5   6

答案 1 :(得分:2)

如何在类似这样的语句中使用coalesce:

update mytable
set a1 = coalesce(a1,a2,a3,a4,a5,a6),
    a2=coalesce(a2,a3,a4,a5,a6), 
    a3=coalesce(a3,a4,a5,a6), 
    a4=coalesce(a4,a5,a6), 
    a5=coalesce(a5,a6)

答案 2 :(得分:0)

如果您无法控制代码或数据库设计,我建议您使用触发器解决此问题。

设置INSERT,UPDATE触发器,专门只查看刚刚更改过的行。这样,您就不会对已经检查过一致性的数据运行更新语句。更少的行检查/更新意味着更好的性能。

您可以通过查看虚拟inserteddeleted表格将其缩小到已触摸的行。

触发器到位后,触摸所有现有行(触发它们的触发器)或运行原始脚本以确保所有行都处于一致状态。

答案 3 :(得分:0)

如果不是这样,您是否尝试在所有列上添加覆盖索引?尝试以下列方式添加索引。这样它可以找到需要更快更新的行,覆盖索引使得它不必进行书签查找以获得所需的下一个值。

A1, A2, A3, A4, A5, A6
A2, A3, A4, A5, A6
A3, A4, A5, A6
A4, A5, A6
A5, A6