Ciò di cui hai bisogno è una "scansione salta" o "scansione dell'indice allentata ". Il pianificatore di PostgreSQL non li implementa ancora automaticamente, ma puoi ingannarlo utilizzandone uno utilizzando una query ricorsiva.
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;
Potrebbe esserci un modo per comprimere max(eventtime) nella query ricorsiva piuttosto che farlo al di fuori di quella query, ma in tal caso non ci sono riuscito.
Questo ha bisogno di un indice su (eventtype, eventtime) per essere efficiente. Puoi farlo essere DESC sull'ora dell'evento, ma non è necessario. Questo è efficiente solo se eventtype ha solo pochi valori distinti (21 di loro, nel tuo caso).