2

PostgreSQL 13.5, PostGIS 3.2, Windows Server 2012.

My table uniteobservation has 824 605 rows:

CREATE TABLE activite.uniteobservation (
gid serial NOT NULL,
numunobs character varying(20),
typunobs character varying(20),
interpret character varying(60,
datedebut bigint,
datefin integer,
gidoperef integer NOT NULL,
geom geometry(Geometry,2154),
periode character varying(50),
CONSTRAINT "UniteObservation_pkey" PRIMARY KEY (gid),
CONSTRAINT clef_etrangere_prescription FOREIGN KEY (gidoperef)
    REFERENCES activite.prescription (gid),
CONSTRAINT epsg_isvalid_check CHECK (
    st_x(st_centroid(geom)) >= 99217::double precision AND
    st_x(st_centroid(geom)) <= 1242417.2::double precision AND
    st_y(st_centroid(geom)) >= 6049646::double precision AND
    st_y(st_centroid(geom)) <= 7110480.1::double precision),
CONSTRAINT uniteobservation_geom_notnull CHECK (geom IS NOT NULL),
CONSTRAINT uniteobservation_isvalid_check CHECK (st_isvalid(geom))

I am trying to execute this query:

select o1.gid gid1, o2.gid gid2 from
activite.uniteobservation o1, activite.uniteobservation o2
where st_equals(o1.geom, o2.geom)
and o1.gid < o2.gid
order by o1.gid, o2.gid

There are indexes on gid and geom columns.

CREATE INDEX idx_unobs_gid
ON activite.uniteobservation USING btree (gid);

CREATE INDEX idx_uniteobservation_geom_gist
ON activite.uniteobservation USING gist (geom);

In the execution plan:

"Gather Merge  (cost=3220744751.29..3388503442.56 rows=1437831248 width=8)"
"  Workers Planned: 2"
"  ->  Sort  (cost=3220743751.27..3222541040.33 rows=718915624 width=8)"
"        Sort Key: o1.gid, o2.gid"
"        ->  Nested Loop  (cost=2068.71..3075671069.76 rows=718915624 width=8)"
"              ->  Parallel Seq Scan on uniteobservation o2  (cost=0.00..97527.85     rows=343585 width=1223)"
"              ->  Bitmap Heap Scan on uniteobservation o1  (cost=2068.71..8951.15 rows=27 width=1223)"
"                    Recheck Cond: (gid < o2.gid)"
"                    Filter: st_equals(geom, o2.geom)"
"                    ->  BitmapAnd  (cost=2068.71..2068.71 rows=275 width=0)"
"                          ->  Bitmap Index Scan on idx_uniteobservation_geom_gist  (cost=0.00..6.50 rows=825 width=0)"
"                                Index Cond: (geom ~= o2.geom)"
"                          ->  Bitmap Index Scan on idx_unobs_gid  (cost=0.00..2061.95 rows=274868 width=0)"
"                                Index Cond: (gid < o2.gid)"

If I can see that the nested loop is very x10 expensive due to the Nested Loop.

I am not familiar with query optimization. So is there any way to reduce the cost this query? Currently, it does not even finish.

EDIT With this query :

EXPLAIN (ANALYZE, BUFFERS) select o1.gid gid1, o2.gid gid2 from
activite.uniteobservation o1, activite.uniteobservation o2
where st_equals(o1.geom, o2.geom)
and o1.gid < o2.gid and o2.gid=13
order by o1.gid, o2.gid

Here is the query plan:

"Sort  (cost=13180.55..13185.94 rows=2154 width=8) (actual time=0.178..0.183 rows=0 loops=1)"
"  Sort Key: o1.gid"
"  Sort Method: quicksort  Memory: 25kB"
"  Buffers: shared read=3"
"  ->  Nested Loop  (cost=5119.17..13061.30 rows=2154 width=8) (actual time=0.161..0.164 rows=0 loops=1)"
"        Buffers: shared read=3"
"        ->  Index Scan using idx_unobs_gid on uniteobservation o2  (cost=0.42..8.44 rows=1 width=1243) (actual time=0.159..0.160 rows=0 loops=1)"
"              Index Cond: (gid = 13)"
"              Buffers: shared read=3"
"        ->  Bitmap Heap Scan on uniteobservation o1  (cost=5118.74..13052.58 rows=28 width=1243) (never executed)"
"              Recheck Cond: (gid < o2.gid)"
"              Filter: st_equals(geom, o2.geom)"
"              ->  BitmapAnd  (cost=5118.74..5118.74 rows=275 width=0) (never executed)"
"                    ->  Bitmap Index Scan on idx_uniteobservation_geom_gist  (cost=0.00..34.47 rows=825 width=0) (never executed)"
"                          Index Cond: (geom ~= o2.geom)"
"                    ->  Bitmap Index Scan on idx_unobs_gid  (cost=0.00..5084.01 rows=275144 width=0) (never executed)"
"                          Index Cond: (gid < o2.gid)"
"Planning Time: 3.798 ms"
"Execution Time: 0.419 ms"
6
  • 1
    For performance questions, please present information as instructed here: dba.meta.stackexchange.com/a/3299/3684. Most importantly, exact table and index definitions (CREATE TABLE and CREATE INDEX statements). And always your version of Postgres (and PostGIS). I am thinking of a multicolumn index on (geom, gid) ... Commented Jan 19, 2022 at 12:29
  • Sorry ,I was ignoring these recommandations. I did my best in editing my first message.
    – Leehan
    Commented Jan 19, 2022 at 14:25
  • I edited out some noise. But let me ask about your sequence name activite."UniteObservation_gid_seq". That suspiciously looks like you have (or had?) a corresponding table "UniteObservation" with double-quotes preserving the dreaded mixed-case spelling. But your table's name is still uniteobservation, right? No confusion there? Commented Jan 19, 2022 at 17:01
  • I am not sure of what you mean (limit of my english) but I hope I have understood : the sequence applies to the column gid of uniteobservation, so to speak the one called in the query i.e. there is no table called uniteObservation.
    – Leehan
    Commented Jan 19, 2022 at 17:43
  • Estimates for geometric joins are not very useful. What do you get if you add AND o2.gid=13 (or some other constant) onto the query? Please show the EXPLAIN (ANALYZE, BUFFERS) for it.
    – jjanes
    Commented Jan 19, 2022 at 23:07

0

Your Answer

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