[postgis-tickets] [PostGIS] #3675: Relationship functions not using an index in some cases
PostGIS
trac at osgeo.org
Thu Nov 9 10:28:26 PST 2017
#3675: Relationship functions not using an index in some cases
----------------------+---------------------------
Reporter: robe | Owner: robe
Type: defect | Status: closed
Priority: blocker | Milestone: PostGIS 2.3.2
Component: postgis | Version: 2.3.x
Resolution: fixed | Keywords:
----------------------+---------------------------
Comment (by pramsey):
OK, our plan fails when we hit an examination of the costs of the
parameters to the function being inlined. Our high-cost ST_SetSRID kicks
things out, so we don't get in-lined.
https://github.com/postgres/postgres/blob/ae20b23a9e7029f31ee902da08a464d968319f56/src/backend/optimizer/util/clauses.c#L4581-L4584
This seems to be generically true, as an example can be constructed in
PgSQL native terms:
{{{
-- Create data table and index. Analyze.
DROP TABLE IF EXISTS boxen;
CREATE TABLE boxen AS
SELECT row_number() OVER() As gid,
box(point(x, y),point(x+1, y+1)) AS b, x, y
FROM generate_series(-100,100) As y, generate_series(-100,100) As x;
CREATE INDEX idx_b_geom_gist ON boxen USING gist(b);
ANALYZE boxen;
-- inlined function
-- when set 'STRICT' it breaks index access
-- 'IMMUTABLE' doesn't seem to bother it
CREATE OR REPLACE FUNCTION good_box(box, box)
RETURNS boolean
AS 'SELECT $1 OPERATOR(&&) $2 AND length(lseg(point($1),point($2))) < 3'
LANGUAGE 'sql';
-- Start with a low cost circle()
ALTER FUNCTION circle(point, double precision) COST 1;
-- [A] Query plan hits index
EXPLAIN SELECT gid
FROM boxen
WHERE good_box(
boxen.b,
box(circle(point(20.5, 20.5), 2))
);
-- [B] Query plan hits index
EXPLAIN SELECT gid
FROM boxen,
(SELECT x, y FROM boxen WHERE x < 0 and y < 0) AS c
WHERE good_box(
boxen.b,
box(circle(point(c.x, c.y), 2))
);
-- Increase cost of circle
ALTER FUNCTION circle(point, double precision) COST 100;
-- [B] Query plan does not hit index
EXPLAIN SELECT gid
FROM boxen,
(SELECT x, y FROM boxen WHERE x < 0 and y < 0) AS c
WHERE good_box(
boxen.b,
box(circle(point(c.x, c.y), 2))
);
}}}
--
Ticket URL: <https://trac.osgeo.org/postgis/ticket/3675#comment:18>
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