• Go by the values in the clustered index.  For example, if the table is clustered on a datetime column, use that as the value for the UPDATE.

    Here's a shell script that lets you specify a starting and max value, batch size to update and total number of rows to update.


    SET ANSI_NULLS ON;
    SET ANSI_PADDING ON;
    SET ANSI_WARNINGS ON;
    SET ARITHABORT ON;
    SET CONCAT_NULL_YIELDS_NULL ON;
    SET NOCOUNT OFF;
    SET NUMERIC_ROUNDABORT OFF;
    SET QUOTED_IDENTIFIER ON;
    SET XACT_ABORT ON;

    DECLARE @batch_size_of_update int;
    DECLARE @datetime datetime;
    DECLARE @max_datetime datetime;
    DECLARE @min_datetime datetime;
    DECLARE @rows_updated int;
    DECLARE @total_rows_updated int;
    DECLARE @total_rows_to_update int;

    SET @batch_size_of_update = 20000;
    SET @total_rows_to_update = 200000;
    SET @min_datetime = '19000101';
    SET @max_datetime = '20171231';
    SET @rows_updated = 0;
    SET @total_rows_updated = 0;

    PRINT 'Start time = ' + CONVERT(varchar(30), GETDATE(), 0) + '.';

    WHILE 1 = 1
    BEGIN
      SELECT TOP (@batch_size_of_update) @datetime = datetime
      FROM dbo.table_name
      WHERE datetime >= @min_datetime AND
       datetime <= @max_datetime
      ORDER BY datetime;
      UPDATE TOP (@batch_size_of_update) tn
      SET whatever = 'whatever'
      FROM dbo.table_name tn
      WHERE datetime >= @min_datetime AND
       datetime <= @datetime;
      SET @rows_updated = @@ROWCOUNT;
      IF @rows_updated = 0
       BREAK;
      SET @total_rows_updated = @total_rows_updated + @rows_updated;
      PRINT 'Total Rows updated = ' + CAST(@total_rows_updated AS varchar(10)) + '.';
      PRINT 'Last datetime updated = ' + CONVERT(varchar(30), @datetime, 120) + '.'
      IF @total_rows_updated >= @total_rows_to_update
       BREAK;
      SET @min_datetime = @datetime;
      IF @total_rows_updated % 200000 = 0
      BEGIN
       CHECKPOINT;
      END; --IF
      IF @batch_size_of_update >= 10000
      BEGIN
       IF @batch_size_of_update <= 25000
        WAITFOR DELAY '00:00:00.125';
       ELSE
       IF @batch_size_of_update <= 50000
        WAITFOR DELAY '00:00:00.250';
       ELSE
        WAITFOR DELAY '00:00:00.500';
      END /*IF*/
    END --WHILE

    CHECKPOINT;

    PRINT '';
    PRINT 'End time = ' + CONVERT(varchar(30), GETDATE(), 0) + '.';

    SQL DBA,SQL Server MVP(07, 08, 09) A socialist is someone who will give you the shirt off *someone else's* back.