Depending on your postgres and/or sql expertise you have several options:
analyze the query through the EXPLAIN command to find out if you're hitting a particular bottleneck. Warning: sometimes the output of EXPLAIN can be difficult to understand
if you expect that most or a significant portion of the geometries in table1 do NOT intersect the multipolygon you could try to apply a preliminary condition against a simpler polygon (i.e. by breaking the multiploygon in smaller pieces) and then run the heavier multipolygon intersection only on those results. See below for an example.
if and only if CPU is the bottleneck (i.e. the server is stuck computing intersections) I dully suggest you get a bigger, faster, more powerful CPU or rent a one-time High-CPU Instance off Amazon's EC2 and destroy it when you're done
Example query for item 2:
SELECT DISTINCT ON (st1.userid) st1.userid ,ST_AsText(st1.position), st1.timestamp
select userid, position, timestamp from table1
WHERE ST_Intersects ( YOUR_MULTIPOL_BOUNDS_HERE,position)
) as st1
WHERE ST_Intersects ( ST_GeomFromText('a multiypolygon geom goes here',4326),st1.position)
ORDER BY st1.userid, st1.timestamp desc
To improve performance you could also temporarily materialize subselect st1 as a table so that you can index it.
@Nicklas is right to point out in the comments that example for suggestion 2 should not help. He is right, but I think I'm (partly) right too.
In fact it seems a very similar question was asked (and answered) just last November on the postgis ML:
and turns out the suggestion is to actually break up the polygon so that the index can most effectively filter out false intersections that would be otherwise triggered by a simple boundary check.