Optimise Large Record Deletion Procedure
I prefer the next strategy: the stored routine that fill up the table on each inserted record also delete few expired ones. This look like that:

BEGIN
-- lot of code --
INSERT INTO table ...
-- lot of code --
DELETE FROM table AS w WHERE w.expire &lt; NOW() LIMIT 3;
END


Insertion/deletion ratio is set to 1:3 just to ensure I get the reasonable  removal rate even when incoming data rate become low due to daily/weekly/monthly oscillations. It is acceptable for established bases with low expired records count. If you want to perform initial cleanup, then you have to set the LIMIT to the value that do not insult your server performance.

If you have low incoming data rate then you can create the special routine ad hoc:

CREATE PROCEDURE table_cleanup()    
BEGIN
main: REPEAT
  DELETE FROM table AS w WHERE w.expire &lt; NOW() LIMIT 1000;
  UNTIL row_count() = 0 END REPEAT main;
END


Huge DELETE will be splitted into the series of small ones that can't lock the tables for a while.