[postgis-tickets] [PostGIS] #3092: Slow performance of geometry_columns in PostGIS >= 2
PostGIS
trac at osgeo.org
Fri Apr 24 15:29:40 PDT 2015
#3092: Slow performance of geometry_columns in PostGIS >= 2
--------------------------+---------------------------
Reporter: rouault | Owner: pramsey
Type: enhancement | Status: new
Priority: high | Milestone: PostGIS 2.1.8
Component: postgis | Version: 2.0.x
Resolution: | Keywords:
--------------------------+---------------------------
Comment (by robe):
Okay here is my proposed. No dependencies on any functions and for my
simple tests the speed seems much better than existing and slower than
yours for full table set but generally faster for filtered set of tables.
{{{
CREATE OR REPLACE VIEW geometry_columns AS
SELECT current_database()::varchar(256) AS f_table_catalog,
n.nspname::varchar(256) AS f_table_schema,
c.relname::varchar(256) AS f_table_name,
a.attname::varchar(256) AS f_geometry_column,
COALESCE(postgis_typmod_dims(atttypmod),
s.dims,
2) AS coord_dimension,
COALESCE(NULLIF(postgis_typmod_srid(atttypmod),0),
s.srid,
0) AS srid,
-- force to be uppercase with no ZM so is backwards compatible
-- with old geometry_columns
replace(
replace(
COALESCE(
NULLIF(upper(postgis_typmod_type(atttypmod)::text), 'GEOMETRY'),
s.type,
'GEOMETRY'
), 'ZM', ''
), 'Z', ''
)::varchar(30) AS type
FROM pg_class c
JOIN pg_attribute a ON a.attrelid = c.oid AND NOT a.attisdropped
JOIN pg_namespace n ON c.relnamespace = n.oid
JOIN pg_type t ON a.atttypid = t.oid
LEFT JOIN
(SELECT connamespace, conrelid, conkey
, MAX( CASE WHEN consrc ILIKE '%geometrytype(% = %' THEN
replace(split_part(consrc, '''', 2), ')', '') ELSE NULL END ) As type
, MAX( CASE WHEN consrc ILIKE '%srid(% = %' THEN
replace(replace(split_part(consrc, ' = ', 2), ')', ''), '(', '')::integer
ELSE NULL END) As srid
, MAX( CASE WHEN consrc ILIKE '%ndims(% = %' THEN
replace(split_part(consrc, ' = ', 2), ')', '')::integer ELSE NULL END) As
dims
FROM pg_constraint
WHERE consrc ILIKE '%geometrytype(% = %' OR consrc ILIKE '%ndims(% = %' OR
consrc ILIKE '%srid(% = %'
GROUP BY connamespace, conrelid, conkey
) AS s ON s.connamespace = n.oid
AND s.conrelid = c.oid
AND a.attnum = ANY (s.conkey)
WHERE c.relkind IN ('r'::"char", 'v'::"char", 'm'::"char", 'f'::"char")
AND NOT ( c.relname = 'raster_columns' )
AND t.typname = 'geometry'::name
AND NOT pg_is_other_temp_schema(c.relnamespace)
AND has_table_privilege( c.oid, 'SELECT'::text );
}}}
For full table scan your version beats by a wide margin. For a 1500 table
set yours comes out
{{{
-- Paul's 140 ms, Regina's 440ms, original 1860ms
SELECT * from geometry_columns;
}}}
-- For filtered the story is a little different
{{{
-- Paul's 80ms, Regina's 40ms, original 640ms
-- 500 rows returned
SELECT * FROM geometry_columns
WHERE f_table_name LIKE 'constraint%point%';
}}}
I still need to test it with multi geom column tables and typmod to make
sure no consequences I missed and also a bigger set of tables. I only
tested with 1500 tables all of constraint type and no typmod so not a
sufficiently complete test.
--
Ticket URL: <http://trac.osgeo.org/postgis/ticket/3092#comment:10>
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