7

I ran out of space in my database, so I did a backup on old records. Now I have to clear these records out, and my reference column is 'date'.

I tried using the standard approach:

DELETE FROM table WHERE date >= '2017-01-01' AND date <= '2017-12-31'

But this is obviously taking too much time, because there are more than 7 million rows to delete. Is there a way to speed this up? I'm trying to divide in months and even smaller chunks, but after running the code for some time, I get disconnected from the server.

Thanks in advance.

EDIT:

CREATE TABLE table (

  id INT(11) NOT NULL AUTO_INCREMENT,
  date DATE DEFAULT NULL,
  # 18 more columns

  PRIMARY KEY (id)
)
ENGINE = INNODB,
AUTO_INCREMENT = 29616055,
AVG_ROW_LENGTH = 317,
CHARACTER SET utf8mb4,
COLLATE utf8mb4_general_ci;
10
  • What have you tried to debug the problem? Is there any index set?
    – Nico Haase
    Commented Feb 18, 2019 at 18:21
  • 2
    Is the table's Engine InnoDB or MyISAM? (or to answer my and Nico's question, add the table's CREATE statement your question).
    – Uueerdo
    Commented Feb 18, 2019 at 18:23
  • It might be that your date field is not indexed.
    – Ibu
    Commented Feb 18, 2019 at 18:24
  • Either MySql or Sql tag please
    – Alex
    Commented Feb 18, 2019 at 18:24
  • 2
    ALTER TABLE `table` ADD INDEX date_index (`date`); What is your column date type is?
    – Alex
    Commented Feb 18, 2019 at 18:27

2 Answers 2

18

If you have enough space, then create a temporary table and re-load the original table:

create table temp_t as
    select *
    from table
    where date >= '2018-01-01';

truncate table t;

insert into t
     select *
     from temp_t;

This saves all the logging overhead for the delete -- and that can be quite expensive.

Next, you need to learn about partitions. This makes the process much much simpler. You can just drop a partition, instead of deleting rows -- and there is no row-by-row logging for dropping a partition.

3
  • 1
    Great. It worked like charm. I have tested this answer on ~1100 million rows and it worked as expected. Thanks for the sharing this answer. Commented Jan 30, 2020 at 6:42
  • This is a great alternative to delete, I wonder how create table can be faster.
    – Joel
    Commented Mar 4, 2020 at 0:00
  • @joel . . . Less logging and minimal impact of locking. Commented Mar 4, 2020 at 2:11
1
  1. Create an empty copy of the table (keys and all).
  2. INSERT...SELECT the data you want to preserve from the original into the copy.
  3. Remove any foreign key constraints referencing the original table.
  4. DROP the original table.
  5. RENAME the copy to the original's name.
  6. Recreate any foreign keys dropped in step 3.

Not the answer you're looking for? Browse other questions tagged or ask your own question.