I'm looking for some insights into why deletes from a fairly simple table seem to be much slower in MySQL8 than in MySQL5.7

Apologies in advance if this is a little fluffy at this stage and I've anonymised the table/column names.

We have a table:

  other_id  BIGINT, -- parent id from another table
  type      INT,
  timestamp BIGINT,
  creator   INT,

  PRIMARY KEY (thing_id),
  KEY (other_id,timestamp),
  KEY (timestamp,type),
  KEY (type,timestamp)
  ENGINE = InnoDb;

...which accumulates a lot of rows (typically millions) and periodically we prune it down to remove old entries. It has a complicated relationship with ids in other tables so we can't prune it based purely on timestamp unfortunately so everything has to be done by ids.

When we do the prune, a working table old_things is built to contain all of the ids of the things to be deleted:

CREATE TABLE old_things (thing_id BIGINT primary key);

...and then we delete in looping batches from the things table using a JOIN with old_things and a BETWEEN range of ids (calculated on each loop using max/min of a query with LIMIT - usually 1000 rows):

DELETE IGNORE th.* FROM things th JOIN old_things t USING (thing_id) WHERE t.thing_id BETWEEN from_thing_id AND to_thing_id;

We're seeing, from slow query performance analysis, that this DELETE command above is taking typically 75% longer in MySQL 8.0.31 than it is in MySQL 5.7.36

For example, a run in which that DELETE query is performed ~33K times (deleting 1000 rows each time) results in 44s total execution time in MySQL 5.7.36 and 77s MySQL 8.0.31

I appreciate I haven't talked about mysql configuration but we've done our best to give the two databases identical settings on identical hardware and we are not using binary logging/replication - this is a standalone mysql instance.

Are there any obvious first ports of call to investigate?

I was wondering if it was something to do with the numerous compound indexes on that table - if I strip away the indexes on the things table and have only a single index (on other_id) then the ~33K execution time in MySQL 8.0.31 drops dramatically to ~10s.

To support this theory we have an accompanying table that has typically the same rowcount but with many more large columns but with only one index (on other_id) and deletes from that table using the same method above are actually showing as faster in MySQL8 than MySQL5.7 (51s vs 58s for 33K executions of that query with 1000 rows deleted each time).

Those numerous compound indexes were put in place to support various queries involving the "things" table but some may be legacy and up for review/removal.

Thank you in advance for any responses.


  • What storage engine were you using on 5.7 vs 8?
    – dwhitemv
    Commented Dec 7, 2022 at 7:35
  • Both innodb. We used the utf8 charset in MySQL 5.7 and the newer default utf8mb3 in MySQL 8 if that's of any relevance? Thanks. Commented Dec 7, 2022 at 12:19
  • In our case we found out that having 10k IDs in a in clause was avoiding to use the index and took hours but for 9k was using index and taking 2s can you show the explain output?
    – vmrvictor
    Commented Feb 24, 2023 at 22:59


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.