Wat je nodig hebt is een "skip scan" of "losse indexscan ". De planner van PostgreSQL implementeert deze nog niet automatisch, maar u kunt er een gebruiken door een recursieve query te gebruiken.
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;
Er kan een manier zijn om de max(eventtime) samen te vouwen in de recursieve query in plaats van het buiten die query te doen, maar als dat zo is, heb ik het niet gevonden.
Dit heeft een index op (eventtype, eventtime) nodig om efficiënt te zijn. Je kunt het DESC hebben op de eventtime, maar dat hoeft niet. Dit is alleen efficiënt als gebeurtenistype slechts een paar verschillende waarden heeft (21 van hen, in uw geval).