HiveBrain v1.2.0
Get Started
← Back to all entries
patternsqlModerate

Bulk Delete for Large Table in MySQL

Submitted by: @import:stackexchange-dba··
0
Viewed 0 times
deletebulkmysqllargefortable

Problem

I have a Notification table contains about 100 million rows host in Amazon RDS with 1000 IOPS, and I want to delete those rows older than one month.

If I do DELETE FROM NOTIFICATION WHERE CreatedAt < DATE_SUB(CURDATE(), INTERVAL 30 day);, all the IOPS will be taken, the process will take hours, and a lot of new entries cannot be inserted due to "Lock wait timeout exceeded; try restarting transaction".

I was trying to do the way describe in here:http://mysql.rjweb.org/doc.php/deletebig
However, I am using UUID instead of increment ID.

What is the correct and efficient way to delete those rows while not affect new data being insert/update?

Solution

Make a temp table, switch it in and out, and copy the last 30 days data into it.

#
# Make empty temp table
#
CREATE TABLE NOTIFICATION_NEW LIKE NOTIFICATION;
#
# Switch in new empty temp table
#
RENAME TABLE NOTIFICATION TO NOTIFICATION_OLD,NOTIFICATION_NEW TO NOTIFICATION;
#
# Retrieve last 30 days data 
#
INSERT INTO NOTIFICATION SELECT * FROM NOTIFICATION_OLD
WHERE CreatedAt >= DATE_SUB(CURDATE(), INTERVAL 30 DAY);


In your off hours, drop the old table

DROP TABLE NOTIFICATION_OLD;


Here are the Advantages to doing DELETEs like this

  • NOTIFICATION is emptied fast by means switching in an empty table.



  • NOTIFICATION is immediately available for new INSERTs



  • The remaining 30 days are added back into NOTIFICATION while new INSERTs can take place.



  • Dropping the old version of NOTIFICATION does not interfere with new INSERTs



  • NOTE : I have recommended doing bait-and-switch for table DELETEs before : (See my July 19, 2012 post : Optimizing DELETE Query on MySQL MEMORY Table)



Give it a Try !!!

Code Snippets

#
# Make empty temp table
#
CREATE TABLE NOTIFICATION_NEW LIKE NOTIFICATION;
#
# Switch in new empty temp table
#
RENAME TABLE NOTIFICATION TO NOTIFICATION_OLD,NOTIFICATION_NEW TO NOTIFICATION;
#
# Retrieve last 30 days data 
#
INSERT INTO NOTIFICATION SELECT * FROM NOTIFICATION_OLD
WHERE CreatedAt >= DATE_SUB(CURDATE(), INTERVAL 30 DAY);
DROP TABLE NOTIFICATION_OLD;

Context

StackExchange Database Administrators Q#83109, answer score: 12

Revisions (0)

No revisions yet.