开发者

SQL UPDATE performing poorly

My database table has the following columns: A1, A2, A3, A4, A5, A6

I have to update these records and shift the values left whenever I come across a null column. The purpose is not to have nul开发者_如何学Pythonl values between the columns that have a value starting from left. For example if:

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

I have to shift the values left so the result will be:

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

So far I have come up with the following query but it is slow. Let me know if you can tweak the query to make it faster. One more thing, What if I do this in c#? Will it be faster if I loop through the Datarows there and update each row?

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)


Given that [anything] + NULL + [anything] is null how about;

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


How about using coalesce in a statement something like this:

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)


If you have no control over the code or the database design, I would recommend solving this problem using a trigger.

Set up an INSERT, UPDATE trigger that will specifically only look at the rows that have just been changed. That way you're not running an update statement on data that has already been checked for consistency. Less rows to check/update means better performance.

You can narrow it down to the rows that have been touched by looking at the virtual inserted and deleted tables.

Once your trigger is in place either touch all of the existing rows (to fire the trigger on them) or run your original script to make sure that everything is in a consistent state.


If not that, have you tried adding covering indexes on all of your columns? Try adding indexes in the following way. This is so that it can find the rows that need updating faster, the covering index is so that it doesn't have to do a bookmark lookup to get the next value it needs.

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜