Performance Tuning UPDATE Statement

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • MAS

    Performance Tuning UPDATE Statement

    Below is a simple UPDATE that I have to perform on a table that has
    about 2.5 million rows (about 4 million in production) This query
    runs for an enourmous amount of time (over 1 hour). Both the
    ChangerRoleID and the ChangerID are indexed (not unique). Is there
    any way to performance tune this?

    Controlling the physical drive of the log file isn't possible at our
    client sites (we don't have control) and the recovery model needs to
    be set to "Full".

    UPDATE CLIENTSHISTORY SET ChangerRoleID = ChangerID WHERE
    ChangerRoleID IS NULL

    Any Help would be greatly appreciated!
  • Hugo Kornelis

    #2
    Re: Performance Tuning UPDATE Statement

    On 4 Aug 2004 08:27:50 -0700, MAS wrote:
    [color=blue]
    >Below is a simple UPDATE that I have to perform on a table that has
    >about 2.5 million rows (about 4 million in production) This query
    >runs for an enourmous amount of time (over 1 hour). Both the
    >ChangerRoleI D and the ChangerID are indexed (not unique). Is there
    >any way to performance tune this?
    >
    >Controlling the physical drive of the log file isn't possible at our
    >client sites (we don't have control) and the recovery model needs to
    >be set to "Full".
    >
    >UPDATE CLIENTSHISTORY SET ChangerRoleID = ChangerID WHERE
    >ChangerRoleI D IS NULL
    >
    >Any Help would be greatly appreciated![/color]

    Hi MAS,

    If you remove the non-unique index on ChangerRoleID before doing the
    update and recreate it afterwards, you'll probably save some time. The
    index could have been useful if only a few of all rows match the IS NULL
    condition, but with over aan hour execution time, I think there are so
    many matches that a full table scan will be quicker. Removing the index
    before doing the update saves SQL Server the extra work of constantly
    having to update the index to keep it in sync with the data. Of course,
    this might affect other queries that execute during the update and would
    have benefited from this index. The index on ChangerID will neither be
    used nor cause extra work for this update.

    Check if there's a trigger that gets fired by the update. If you can
    safely disable that trigger during the update process, do so. Same for
    constraints: are there any CHECK or REFERENCES (foreign key) constraints
    defined for ChangerRoleID? If so, disable constraint checking (again, only
    if it is safe, i.e. you have to be sure that this update won't cause
    violation of the constraint *and* that no other person accessing the
    database during the time constraint checking is disabled will be able to
    cause violations of the constraint).

    You state that the recovery model needs to be full; from that I conclude
    that you can't lock other users out of the database during the update. Can
    you at least take measures to prevent other users from using (updating,
    but preferably reading as well) the CLIENTSHISTORY table?


    Best, Hugo
    --

    (Remove _NO_ and _SPAM_ to get my e-mail address)

    Comment

    • Erland Sommarskog

      #3
      Re: Performance Tuning UPDATE Statement

      [posted and mailed, please reply in news]

      MAS (mas32677@hotma il.com) writes:[color=blue]
      > Below is a simple UPDATE that I have to perform on a table that has
      > about 2.5 million rows (about 4 million in production) This query
      > runs for an enourmous amount of time (over 1 hour). Both the
      > ChangerRoleID and the ChangerID are indexed (not unique). Is there
      > any way to performance tune this?
      >
      > Controlling the physical drive of the log file isn't possible at our
      > client sites (we don't have control) and the recovery model needs to
      > be set to "Full".
      >
      > UPDATE CLIENTSHISTORY SET ChangerRoleID = ChangerID WHERE
      > ChangerRoleID IS NULL
      >
      > Any Help would be greatly appreciated![/color]

      To add to what Hugo said, if that index on ChangerRoleID is clustered,
      and many rows have a NULL value, then you are in for a problem.

      It may help to do it batches:

      DECLARE @batch_size int, @rowc int
      SELECT @batch_size = 50000
      SELECT @rowc = @batch_size
      SET ROWCOUNT @batch_size
      WHILE @rowc = @batch_size
      BEGIN
      UPDATE CLIENTSHISTORY SET ChangerRoleID = ChangerID
      WHERE ChangerRoleID IS NULL
      AND ChangerID IS NOT NULL
      SELECT @rowc = @@rowcount
      END
      SET ROWCOUNT 0

      --
      Erland Sommarskog, SQL Server MVP, esquel@sommarsk og.se

      Books Online for SQL Server SP3 at
      SQL Server 2025 redefines what's possible for enterprise data. With developer-first features and integration with analytics and AI models, SQL Server 2025 accelerates AI innovation using the data you already have.

      Comment

      Working...