Wednesday, April 6, 2011

Update with inner join to same table optimizations

The query is:

CREATE TABLE logfile (
   sequence_number BIGINT,
   start_time DECIMAL,
   finish_time DECIMAL,
   irp_major VARCHAR(100),
   offset BIGINT,
   length BIGINT,
   filename VARCHAR(2000),
   is_seq BIT 
   );
//bulk insert 120 000 rows
CREATE CLUSTERED INDEX IX_logfile ON logfile(sequence_number); 
UPDATE dbo.logfile SET is_seq = (
SELECT  CASE WHEN a.offset = (b.offset + b.length) THEN 1 ELSE 0 END AS seq
FROM    dbo.logfile a
        LEFT JOIN dbo.logfile b
            ON a.sequence_number = b.sequence_number + 1
WHERE a.sequence_number = logfile.sequence_number)

Is there anyway I can improve the performance of the update query?

From stackoverflow
  • MERGE
    INTO logfile l
    USING (
      SELECT sequence_number + 1 AS pseq,
             p.*
      FROM logfile p
    ) pl
    ON l.sequence_number = pseq
    WHEN MATCHED THEN
      UPDATE
      SET is_seq = CASE WHEN l.offset = (pl.offset + pl.length) THEN 1 ELSE 0 END
    
    Lieven : @Quassnoi. Different result or not, I did (again) learned something new. Thx.
    devzero : ahh found the error: sequence_number - 1 should be sequence_number + 1. Works great now, speed is more or less equivalent to @lievens, both are order of magnitude better than mine :)
    Quassnoi : Sure, missed it.
  • Perhaps this update would be faster

    UPDATE dbo.LogFile SET is_seq = 0
    UPDATE dbo.LogFile SET is_seq = 1
    FROM dbo.LogFile f
         INNER JOIN (
           SELECT f2.sequence_number
           FROM dbo.LogFile f1
                INNER JOIN dbo.LogFile f2 ON f2.sequence_number = f1.sequence_number + 1     
           WHERE f1.Offset <> f2.Offset + f2.Length
         ) f2 ON f2.sequence_number = f.sequence_number
    

0 comments:

Post a Comment