One of my servers runs a query once a week to remove all rows from a Syslog table (>20,000,000 rows) in a MySQL database that are older than 60 days. This was running terribly slowly and interfering with other tasks on the server.
Although the original query used a DELETE statement I’ve used SELECT statements in the examples below.
SELECT COUNT(*)
FROM SystemEvents
WHERE ReceivedAt < DATE_SUB(NOW(), INTERVAL 60 DAY);
That selects about 900,000 rows and takes about 45 seconds.
SELECT COUNT(*)
FROM SystemEvents
WHERE ReceivedAt < DATE_ADD(CURRENT_DATE, INTERVAL -60 DAY);
Likewise takes about 48 seconds.
Is MySQL running a function every time it makes a comparison? I decided to try using a hard-coded date to find out:
SELECT COUNT(*)
FROM SystemEvents
WHERE ReceivedAt < '2015-11-12 12:00:00';
6 seconds! Much faster.
I created a user-defined variable:
SET @sixty_days_ago = DATE_SUB(NOW(), INTERVAL 60 DAY);
Then ran the query:
SELECT COUNT(*)
FROM SystemEvents
WHERE ReceivedAt < @sixty_days_ago;
12 seconds. No 6 seconds, but still a fraction of the original time!