I have a table of meetings, each of which has a start and end time expressed as an integer Unix timestamp, as well as a group of people who are attending this meeting. I need to send out notifications to each group of people once all their meetings for the day have completed. To do this I need to find the last meeting for every combination of (day, group). I've adapted this answer for my situation, and it works:
SELECT MAX(`starts_at`), `id`, `group_id`, DATE(FROM_UNIXTIME(`starts_at`)) `day`
FROM `meeting`
GROUP BY `day`, `group_id`;
However, despite trying out different combinations of indexes, I can't seem to find one that would make this query not perform a full-table scan. The EXPLAIN
result is always as follows:
+------+-------------+---------+------+---------------+------+---------+------+------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+---------+------+---------------+------+---------+------+------+---------------------------------+
| 1 | SIMPLE | meeting | ALL | NULL | NULL | NULL | NULL | 16 | Using temporary; Using filesort |
+------+-------------+---------+------+---------------+------+---------+------+------+---------------------------------+
My table is defined this way:
CREATE TABLE `meeting` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`group_id` int(11) NOT NULL,
`starts_at` int(11) NOT NULL,
`ends_at` int(11) NOT NULL,
... other fields ...,
PRIMARY KEY (`id`),
CONSTRAINT `meeting_ibfk_1` FOREIGN KEY (`group_id`) REFERENCES `group` (`id`),
)
What combination of indexes, and what query, would I need here? One of the solutions I see is to create an indexed column that stores the event's day, perhaps as some sort of ordinal, and while this is an option I'd prefer to avoid it if possible in order to not have redundant values in a single row.