[postgis-tickets] [PostGIS] #2083: ST_RemEdgeModFace performance review
PostGIS
trac at osgeo.org
Tue Mar 22 09:03:47 PDT 2022
#2083: ST_RemEdgeModFace performance review
--------------------------+-----------------------------
Reporter: strk | Owner: strk
Type: enhancement | Status: new
Priority: medium | Milestone: PostGIS Fund Me
Component: topology | Version: 2.0.x
Resolution: | Keywords: performance
--------------------------+-----------------------------
Comment (by strk):
I'm digging further in this, executing each query executed internally by
ST_RemEdgeModFace.
The first query looks like this:
{{{
select
r.topogeo_id, r.layer_id, l.schema_name, l.table_name, l.feature_column
FROM topology.layer l
INNER JOIN <TOPONAME>.relation r
ON (l.layer_id = r.layer_id)
WHERE l.level = 0 AND l.feature_type IN ( 2, 4 )
AND l.topology_id = :topology_id
AND r.element_type = 2 AND abs(r.element_id) = :edge_id;
}}}
The conditions used on the relation table are: layer_id, element_type,
element_id.
The index is created with fields: layer_id, topogeo_id, element_type,
element_id -- this makes literal (query) values only usable in the order
given, so since we do NOT have a 'topogeo_id' literal, the only usable
literal is 'layer_id', which in the case I'm looking at matches *all*
records, thus the planner decides to use a sequential scan.
If the unique index was created with reordered fields (layer_id,
element_type, element_id, topogeo_id) it would then be possibly usable for
filtering on element_type, and if we changed the abs(r.element_id) to an
r.element_id in (10, -10) we'd have the possibility to also make juse of
the element_id in the filter. But reordering might slow down other uses
(fetching elements of a known topogeometry) so this is not the best way to
proceed.
Rewriting this query is thus NOT a viable solution.
A new index could serve queries searching for TopoGeometry objects using a
given element of the topology.
Elements of a topology are always identified by the tuple ( layer_id,
element_type, element_id ) because the *same* element_id may have
different meanings based on element_type and layer_id. Among the three
fields, element_id is probably always the most selective.
The next query, only performed if the edge to be removed has left_face !=
right_face, looks like this:
{{{
SELECT t.* FROM (
SELECT
r.topogeo_id,
r.layer_id,
l.schema_name,
l.table_name,
l.feature_column,
array_agg(r.element_id) as elems
FROM topology.layer l
INNER JOIN "${TOPO}".relation r ON (l.layer_id = r.layer_id)
WHERE l.level = 0 and l.feature_type IN (3, 4)
AND l.topology_id = id(findTopology('${TOPO}'))
AND r.element_type = 3
AND r.element_id = ANY (ARRAY[${LEFT_FACE}, ${RIGHT_FACE}]::int4[])
GROUP by
r.topogeo_id, r.layer_id, l.schema_name,
l.table_name, l.feature_column
) t
WHERE NOT t.elems @> ARRAY[${LEFT_FACE}, ${RIGHT_FACE}]::int4[];
}}}
The conditions used on the table are: element_type and element_id, no
layer_id in this case as we're looking for faces in any non-hierarchical
layer.
--
Ticket URL: <https://trac.osgeo.org/postgis/ticket/2083#comment:13>
PostGIS <http://trac.osgeo.org/postgis/>
The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project.
More information about the postgis-tickets
mailing list