Oh ok, so it is not as simple as eliminating all "Seq Scan" occurrences...

Thank you for replying Andrew -

On Sat, Jan 5, 2019 at 9:18 PM Andrew Gierth <and...@tao11.riddles.org.uk>
wrote:

That seems slow in itself, even before adding the extra join - the
> explain suggests that you're both short on indexes and you're getting
> pretty bad plans, possibly due to exceeding join_collapse_limit.
>
> (You might try increasing that in your config, along with
> from_collapse_limit; the default values are a legacy of the days when
> CPUs were much slower and planning time more of an issue.)
>
>  AF> but after I have added a LEFT JOIN with the following table, the
>  AF> query takes 7-10 seconds for completion and makes the game
>  AF> unpleasant to play:
>
>  AF>     # \d words_geoip;
>  AF>                      Table "public.words_geoip"
>  AF>      Column |       Type       | Collation | Nullable | Default
>  AF>     --------+------------------+-----------+----------+---------
>  AF>      block  | inet             |           | not null |
>  AF>      lat    | double precision |           |          |
>  AF>      lng    | double precision |           |          |
>  AF>     Indexes:
>  AF>         "words_geoip_pkey" PRIMARY KEY, btree (block)
>
> And here's yet another missing index, resulting in your query having to
> process and discard 27 million rows in the course of generating a result
> of only 9 rows:
>
>   Join Filter: (CASE WHEN (g.player1 = 5) THEN u2.ip ELSE u1.ip END <<
> i2.block)
>   Rows Removed by Join Filter: 27660682
>
> (you probably wanted <<= rather than << as that comparison, if there's
> any chance your geoip table might have entries for single IPs)
>
> Fortunately, this being pg10, you can use either of these indexes:
>
> CREATE INDEX ON words_geoip USING gist (block inet_ops);
>
> or
>
> CREATE INDEX ON words_geoip USING spgist (block);
>
> As for the rest of the query, here are places you could probably
> work on:
>
>  AF>     LEFT JOIN words_moves m ON m.gid = g.gid
>  AF>             AND NOT EXISTS (SELECT 1
>  AF>                     FROM words_moves m2
>  AF>                     WHERE m2.gid = m.gid
>  AF>                     AND m2.played > m.played)
>
> Whar you're asking for here is that the words_moves row that you're
> joining not have a matching row with a larger "played" value. You can do
> this far more efficiently with a lateral join, given the right index.
>
>  AF>     LEFT JOIN words_social s1 ON s1.uid = 5
>  AF>             AND NOT EXISTS (SELECT 1
>  AF>                     FROM words_social s
>  AF>                     WHERE s1.uid = s.uid
>  AF>                     AND s.stamp > s1.stamp)
>  AF>     LEFT JOIN words_social s2 ON s2.uid = (CASE WHEN g.player1 = 5
> THEN
>  AF> g.player2 ELSE g.player1 END)
>  AF>             AND NOT EXISTS (SELECT 1
>  AF>                     FROM words_social s
>  AF>                     WHERE s2.uid = s.uid
>  AF>                     AND s.stamp > s2.stamp)
>
> Similar considerations apply to both of the above.
>
>  AF>     WHERE 5 IN (g.player1, g.player2)
>  AF>     AND (g.finished IS NULL OR g.finished > CURRENT_TIMESTAMP -
> INTERVAL '1
>  AF> day');
>
> This WHERE clause could be written as
>
>   WHERE 5 IN (g.player1, g.player2)
>     AND coalesce(g.finished,'infinity') > (current_timestamp - interval '1
> day')
>
> and you could then create the following indexes,
>
> CREATE INDEX ON words_games (player1, coalesce(finished,'infinity'));
> CREATE INDEX ON words_games (player2, coalesce(finished,'infinity'));
>
> which should get you a BitmapOr plan for that condition.
>
>  AF> I have also asked my question at [dba.stack]
>
> If you ask questions like this on the IRC channel (#postgresql on
> chat.freenode.net - see http://freenode.net for info or web-based client
> access), you can usually get feedback in real time (I rarely answer
> performance questions in email because getting responses just takes too
> long). You may have to be patient.
>
>
I will try to digest your information and to follow up... Thanks again

For IRC I am unfortunately too tired right now (evening in Germany)

Regards
Alex

Reply via email to