Vad du behöver är en "hoppa över genomsökning" eller "lös indexskanning ". PostgreSQL:s planerare implementerar ännu inte dessa automatiskt, men du kan lura den att använda en genom att använda en rekursiv fråga.
WITH RECURSIVE t AS (
SELECT min(eventtype) AS eventtype FROM allevents
UNION ALL
SELECT (SELECT min(eventtype) as eventtype FROM allevents WHERE eventtype > t.eventtype)
FROM t where t.eventtype is not null
)
select eventtype, (select max(eventtime) from allevents where eventtype=t.eventtype) from t;
Det kan finnas ett sätt att kollapsa max(eventtime) i den rekursiva frågan istället för att göra det utanför den frågan, men i så fall har jag inte träffat det.
Detta behöver ett index på (eventtype, eventtime) för att vara effektivt. Du kan ha det vara DESC på eventtime, men det är inte nödvändigt. Detta är effektivt endast om eventtype bara har ett fåtal distinkta värden (21 av dem, i ditt fall).