I have an InnoDB MySQL table of this structure:
column | type |
---|---|
service | varchar(16) |
url | varchar(255) |
datetime | datetime |
It contains logs for requests made to one of multiple services. It contains ~3 million rows, and gets ~3 million more rows a month (but I will delete old data if need be).
I am trying to generate a report, and get the number of requests made to each service within a date range.
Here is my current query:
SELECT service, COUNT(*) as lastMonthCount
FROM request_logs
WHERE datetime > '2021-02-16 10:51:05'
GROUP BY service
This works, but is painfully slow (~28 seconds).
It outputs this:
service | lastMonthCount |
---|---|
API A | 3056752 |
API B | 38451 |
I have indexes on datetime
and service
. I can see they are of type BTREE
.
How can I radically speed up this query, or restructure my table/indexes so I can achieve the same use case another way?
datetime
and a separate index forservice
resulting in a total of 2 indexes, or do you have 1 single index on both fields? 28 seconds actually doesn't sound too bad for MySQL for that many rows, especially with aVARCHAR(16)
being one of the indexed predicates, but I'll think if there's an architectural improvement you can make, as it sounds like you're close as far as indexes go.VARCHAR(16)
, that could be changed, since the services are known and won't change often. What do you think would be best, an Enum or?DELETE
.