0

We have a system that loads data and then conducts data QC in PostgreSQL. The QC function's performance fluctuates drastically in one of our environments with no apparent pattern. I was able to track down the performance of the following simple query in the QC function:

WITH foo AS (SELECT full_address, jsonb_agg (gad_rec_id) gad_rec_ids
            FROM azgiv.v_full_addresses 
            WHERE gad_gly_id = 495
            GROUP BY full_address 
            HAVING count(1) > 1)
SELECT gad_nguid, gad_rec_id, foo.full_address
        FROM azgiv.v_full_addresses JOIN foo
            ON foo.full_address = v_full_addresses.full_address
        AND v_full_addresses.gad_gly_id = 495;

When I ran into slow-performance situation (Fig 2), I had to ANALYZE the table behind the view before the query plan changes to fast (Fig 1). The v_full_addresses is a simple view of a partitioned table with bunch of columns concatenated.

Here are two images of the query plans for the above query. I am newbie when comes to understanding query optimization and any help is greatly appreciated.

Fast query Plan & Slow query plan

3
  • The images are hard to read and contain little information. You should show the EXPLAIN (ANALYZE, BUFFERS) as text. Commented Oct 20, 2020 at 14:53
  • It might be a typo or a simplification for StackOverflow but as far as I can see the result of the jsonb_agg() isn't used anywhere in the query further on; leaving it out might save you some CPU cycles. Also, if I may ask, what did you use to create those query plan diagrams? Commented Oct 22, 2020 at 8:55
  • 1
    @deroby I used PgAdmin IV to generate the diagram. Commented Nov 14, 2020 at 19:17

1 Answer 1

2

If performance improves after you ANALYZE a table, that means that the database's knowledge about the distribution of the data is outdated.

The best remedy is to tell PostgreSQL to collect these statistics more often:

ALTER TABLE some_table SET (autovacuum_analyze_scale_factor = 0.02);

0.02 is five times lower than the default 0.1, so statistics will be gathered five times more often.

If the bad query plans are generated right after a bulk load, you must choose a different strategy. In this case the problem is that it takes up to a minute for auto-analyze to kick in and calculate new statistics.

In that case you should run an explicit ANALYZE at the end of the bulk load.

Sign up to request clarification or add additional context in comments.

3 Comments

I set the 16 partitioned tables with the parameter which improved, but did not solve the consistency issue. So for the moment, in the load function, I added table ANALYZE right after the bulk data insertions. I feel it is not ideal, until I have more time to play with autovacuum parameters such as naptime and max_worker. Thanks!
That is the elegant solution. See my updated answer.
Great. Thank you so much, Laurenz!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.