1

After upgrading PG from 11 to 15, I struggeling with the following situation:

old (working) Setup: Postgres 11 PostGIS 2.5

Setup: Postgres 15 PostGIS 3.3

table_1 (~14.000.000 rows)

When I do select count(*) from table_1 it never seems to be finished. When I do select * into table_2 from table_1 and than select count(*) from table_2, it would finished in ~15 minutes.

The concrete statements are:

-- this never stops
select count(*)
FROM table_1 t1
INNER JOIN table_1 t2 ON (ST_Equals(t1.wkb_geometry, t2.wkb_geometry))
WHERE t1.gid > t2.gid
;
-- this works
select *
into table_2
from table_1 
;
select count(*)
FROM table_2 t1
INNER JOIN table_2 t2 ON (ST_Equals(t1.wkb_geometry, t2.wkb_geometry))
WHERE t1.gid > t2.gid
;

In both cases there is an index created on wkb_geometry, like this:

CREATE INDEX table_1_geom ON table_1 
USING gist (wkb_geometry)
TABLESPACE pgdata;

I already recreated the index an vacuum the table, but nothing worked for me.

Update: I figured out, that the problem is located at the pkey for column gid. After the select into... table_2 has no pkey on gid. If i remove that pkey on table_1 it would work, too. So what happend by adding a pkey different in PG version 15? Any ideas?

Update 2: DDL/SQL for table_1

SELECT ST_MakeLine(sp,ep) AS wkb_geometry, 
         ogc_fid,
         ...
    INTO table_1
    FROM
       (SELECT
          ST_PointN(geom, generate_series(1, ST_NPoints(geom)-1)) as sp,
          ST_PointN(geom, generate_series(2, ST_NPoints(geom)  )) as ep,
          ogc_fid,
          ...
        FROM
           (SELECT (ST_Dump(ST_Boundary(wkb_geometry))).geom, 
                   ogc_fid,
                   ...
           FROM another_table
           ) AS linestrings
        ) AS segments;
    
    ALTER TABLE table_1 ADD COLUMN gid serial NOT NULL;
    --ALTER TABLE table_1 ADD CONSTRAINT table_1_pk PRIMARY KEY (gid);
    CREATE INDEX table_1_geom ON table_1 USING gist (wkb_geometry) TABLESPACE pgdata;
4
  • Could you please share the result from explain for this query? (usually I would ask for all the details using analyze, verbose, buffers, settings, but when it takes too long, lets start with just explain) And the complete DDL for both tables and all their indexes. All in plain text, as an update of your question. Commented Apr 9, 2024 at 13:59
  • @FrankHeikens: I've added the DDL. When I added the Primary Key (as shown in the second ALTER TABLE statement) all following operation will never finish (e.g. a simple count(*) like my previous statement above). Without the PKey there are no problems. All of these statements ran under PostgeSQL 11 without any problems... Commented Apr 10, 2024 at 6:47
  • @no11 -- doing an explain is not the same as the query running without error. try it. Commented Apr 10, 2024 at 15:22
  • I don't see the DDL for the tables, the CREATE TABLE statements. And there is only one index, the rest is missing or hasn't been created at all and could be the root cause of your performance problem. And no explain either. Commented Apr 10, 2024 at 15:34

1 Answer 1

-1

This question talks about how you can check the statistics on the index

How do I know if the statistics of a Postgres table are up to date?

I think the problem is probably that over time the index got stale -- if you are not updating the statistics on a table they can go "bad" and then they won't work. When you make a new table you make a new index so the new one always has fresh statistics.

If you are to lazy for all that you can also drop the index and re-create it. If that fixes the problem then you know you need to set up a background job to update the statistics every so often (every week?)

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

2 Comments

But I already have re-created the index at table_1 without success. Strangly, table_1 is 2.9 GB and table_2 just 2.5 GB. But table_2 ist just a copy (select into) of table_1.
Updating the statistics is done by the autovacuum/autoanalyze proces. It might need some configuration changes, that can be done on cluster level but also table level. No need for an extra background job, it's already there.

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.