Pre-fetch user ids for presence query.
Pre-fetch user ids for presence query.

Before this commit, postgres would choose a non-optimal query
plan to find all presence rows belonging to a realm.  We now
do an extra query to get the list of relevant user_ids, which allows
the next query to take advantage of UserPresence's index on
user_profile_id.

Here is the query plan for the offending query (this particular query isn't
verbatim from the code, but it's representative of the problem):

    explain analyze
    select client_id
    from zerver_userpresence
    INNER JOIN zerver_userprofile ON
        zerver_userprofile.id = zerver_userpresence.user_profile_id
    WHERE
        zerver_userprofile.is_active and
        zerver_userprofile.realm_id = 3;

     Hash Join  (cost=149.66..506.82 rows=5007 width=4) (actual time=48.834..121.215 rows=5007 loops=1)
       Hash Cond: (zerver_userprofile.id = zerver_userpresence.user_profile_id)
       ->  Seq Scan on zerver_userprofile  (cost=0.00..260.11 rows=5369 width=4) (actual time=0.009..24.322 rows=5021 loops=1)
             Filter: (is_active AND (realm_id = 3))
             Rows Removed by Filter: 3
       ->  Hash  (cost=87.07..87.07 rows=5007 width=8) (actual time=48.789..48.789 rows=5010 loops=1)
             Buckets: 1024  Batches: 1  Memory Usage: 196kB
             ->  Seq Scan on zerver_userpresence  (cost=0.00..87.07 rows=5007 width=8) (actual time=0.007..24.355 rows=5010 loops=1)
     Total runtime: 145.063 ms

You can see above that we're filtering on realm_id instead of using an index.

When you decompose the query into two queries, the total time is about 100ms, for a
savings of 33%.  I imagine the savings would be even greater on an instance with lots
of realms.  This was tested on dev with one really large realm and one tiny realm.

zulip/zulip,rht/zulip,showell/zulip,rht/zulip,hackerkid/zulip,hackerkid/zulip,zulip/zulip,synicalsyntax/zulip,mahim97/zulip,verma-varsha/zulip,rishig/zulip,tommyip/zulip,rishig/zulip,brainwane/zulip,mahim97/zulip,dhcrzf/zulip,andersk/zulip,timabbott/zulip,kou/zulip,showell/zulip,Galexrt/zulip,zulip/zulip,amanharitsh123/zulip,eeshangarg/zulip,tommyip/zulip,timabbott/zulip,eeshangarg/zulip,punchagan/zulip,brainwane/zulip,brainwane/zulip,rishig/zulip,jackrzhang/zulip,tommyip/zulip,amanharitsh123/zulip,rht/zulip,rishig/zulip,kou/zulip,eeshangarg/zulip,timabbott/zulip,brockwhittaker/zulip,rishig/zulip,dhcrzf/zulip,amanharitsh123/zulip,jackrzhang/zulip,brainwane/zulip,mahim97/zulip,rht/zulip,Galexrt/zulip,jackrzhang/zulip,jackrzhang/zulip,Galexrt/zulip,shubhamdhama/zulip,shubhamdhama/zulip,rht/zulip,eeshangarg/zulip,Galexrt/zulip,brockwhittaker/zulip,shubhamdhama/zulip,timabbott/zulip,punchagan/zulip,jackrzhang/zulip,kou/zulip,eeshangarg/zulip,eeshangarg/zulip,kou/zulip,dhcrzf/zulip,tommyip/zulip,synicalsyntax/zulip,timabbott/zulip,zulip/zulip,tommyip/zulip,kou/zulip,verma-varsha/zulip,andersk/zulip,rishig/zulip,showell/zulip,Galexrt/zulip,kou/zulip,amanharitsh123/zulip,punchagan/zulip,tommyip/zulip,brainwane/zulip,Galexrt/zulip,andersk/zulip,zulip/zulip,punchagan/zulip,synicalsyntax/zulip,hackerkid/zulip,rishig/zulip,rht/zulip,eeshangarg/zulip,dhcrzf/zulip,verma-varsha/zulip,showell/zulip,andersk/zulip,hackerkid/zulip,verma-varsha/zulip,timabbott/zulip,andersk/zulip,brainwane/zulip,tommyip/zulip,punchagan/zulip,jackrzhang/zulip,shubhamdhama/zulip,synicalsyntax/zulip,mahim97/zulip,rht/zulip,hackerkid/zulip,shubhamdhama/zulip,brockwhittaker/zulip,dhcrzf/zulip,showell/zulip,shubhamdhama/zulip,brockwhittaker/zulip,hackerkid/zulip,verma-varsha/zulip,andersk/zulip,synicalsyntax/zulip,mahim97/zulip,mahim97/zulip,timabbott/zulip,brockwhittaker/zulip,hackerkid/zulip,brainwane/zulip,brockwhittaker/zulip,punchagan/zulip,showell/zulip,verma-varsha/zulip,kou/zulip,zulip/zulip,amanharitsh123/zulip,Galexrt/zulip,punchagan/zulip,amanharitsh123/zulip,zulip/zulip,jackrzhang/zulip,shubhamdhama/zulip,showell/zulip,synicalsyntax/zulip,synicalsyntax/zulip,andersk/zulip,dhcrzf/zulip,dhcrzf/zulip