Ваш индекс должен охватывать все столбцы, используемые в запросе для максимальной производительности.
Я не уверен в производительности вложенного запроса в этом случае. Я бы предпочел присоединиться к подзапросу, если план выполнения не показывает, что он преобразует его в хорошее вложенное соединение.
Для чего-то подобного, я мог бы избежать UUID, если это возможно, а если нет, я бы позаботился о его увеличении, чтобы вы могли написать:
SELECT actiondate
,status
FROM actions
INNER JOIN (
SELECT username
,MAX(uuid) as last_uuid from actions
WHERE actiondate < 20061231
GROUP BY username
) AS last_occur
ON last_occur.username = actions.username
AND last_occur.last_uuid = actions.uuid
WHERE actiondate < 20061231
Я думаю, что это должно хорошо работать с индексом имени пользователя ASC, uuid DESC, INCLUDE (actiondate) и индексом actiondate DESC, именем пользователя ASC, INCLUDE (status), но, очевидно, посмотрите на план запроса.
Без увеличения uuids вам понадобится какое-то правило, гарантирующее, что вы выбираете последнее действие для человека, поскольку, если имя пользователя, actiondate не является уникальным, в вашем исходном ORDER BY actiondate DESC ограничение 1 не гарантирует вас выбирают правильный ряд каждый раз. Если имя пользователя, actiondate уникальны, вы можете использовать следующее:
SELECT actiondate
,status
FROM actions
INNER JOIN (
SELECT username
,MAX(actiondate) as last_actiondate from actions
WHERE actiondate < 20061231
GROUP BY username
) AS last_occur
ON last_occur.username = actions.username
AND last_occur.last_actiondate = actions.actiondate
WHERE actiondate < 20061231
Если он не уникален, он все равно будет работать, но вы получите несколько действий для человека в его последнюю дату действия. В этом случае рекомендуемые индексы также будут другими (и лучше), поскольку большой uuid не требуется.