Mysql – I need help to optimize a long query

MySQLoptimization

I have a table Chron containing the following columns:

ID | timestamp | …

Some timestamps have been erroneously changed to a specific date D. I want to change them to the timestamp of the nearest rows (in terms of ID) which have not been changed. My query is:

UPDATE Chron as C1
SET C1.timestamp = (
                    SELECT C2.timestamp
                    FROM Chron as C2
                    WHERE C2.timestamp != D
                    AND NOT EXISTS (
                        SELECT *
                        FROM Chron as C3
                        WHERE ABS(C2.id - C1.id) >
                              ABS(C3.id - C1.id)
                    )
)
WHERE C1.timestamp = D

The problem is that my table contains more than 300K rows and this query would take a lot of time to run. How can I optimize it? I know that it is not necessary to compare a given row C1 with the whole table, but just the neighbourhood is sufficient, but the optimal size of the neighbourhood is not always the same.

Best Answer

Here I suppose that id is ordered chronologically just like timestamp field.

UPDATE Chron AS w
   SET w.timestamp = IF( w.timestamp = D, @ts, @ts := w.timestamp )
 ORDER BY w.id ASC
;

The only requirement is that first (by id) record should have the correct timestamp.

Also that query update the broken timestamp to the value of the previous correct/corrected row and if you have the long continuous run of rows with broken timestamps result will be different from the "closest value". Anyway the "closest value" need a complicated query so "previous value" is good enough if you need some fast solution.