Trying to optimise MySQL query which uses Group by with Max. Trying to get latest updated frames which were active before any past date.
Audit Frame Table Structure:
id bigint pk AI
frame_id bigint fk
name VARCHAR(50)
active int
createdOn DATETIME
updatedOn DATETIME
deletedOn DATETIME
id, frame_id and updatedOn have individual indexes..
Current Query:
SELECT MAX(id) as id1
FROM audit_frame_master
WHERE updatedOn <='2019-03-25 21:00:00'
AND active=1
AND deletedOn IS NULL
GROUP
BY frame_id
Performance:
Table has around 1M rows. It takes average 4 seconds to perform.. Is there any way to optimise above query?
The query looks fine. All you can do is provide an appropriate index. That would be an index on the columns in the WHERE
clause at least. Start with the most restrictive column. So,
active = 1
?deletedOn IS NULL
?updatedOn <= timestamp '2019-03-25 21:00:00'
?Pick the one that gets the least number of rows. Say it's active
, then updatedOn
, then deletedOn
. This gives you:
create index idx on audit_frame_master(active, updatedOn, deletedOn);
As you want to group by frame_id
then and then find the maximum id
, you can add those in this order:
create index idx on audit_frame_master(active, updatedOn, deletedOn, frame_id, id);
This is a covering index. If the DBMS uses it, it doesn't even have to access the table.
The DBMS may or may not use this index. It's just an offer. If the DBMS thinks it will be too much work to go through an index rather then simply read the table sequentially, then it won't use it. Just try.