Вы можете упростить ваш запрос до:
SELECT object_id
FROM activity
WHERE user = 'user1' AND
type IN ('add_favorite', 'remove_favorite');
Тогда я бы порекомендовал агрегирование:
SELECT object_id
FROM activity
WHERE user = 'user1' AND
type IN ('add_favorite', 'remove_favorite')
GROUP BY object_id
HAVING SUM(type = 'add_favorite') > SUM(type = 'remove_favorite');
Получает объекты, которые имеют net больше добавлений, чем удаляет.
В качестве альтернативы можно посмотреть на действие last и выбрать только те из них, которые добавляются:
SELECT a.object_id
FROM activity a
WHERE a.user = 'user1' AND
a.timestamp = (SELECT MAX(a2.timestamp)
FROM activity a2
WHERE a2.user = a.user AND
a2.type IN ('add_favorite', 'remove_favorite')
) AND
a.type = 'add_favorite'
С индексом activity(user, type, timestamp)
это, вероятно, имеет лучшую производительность.