Skip to content
Permalink
Browse files

Limit number of rows for Postgis retrieveLayerTypes

When PostgreSQL databases have many millions of objects with a geometry attribute
the PostGIS dataprovider for inspecting tables/fields takes over 15 minutes for each table to open.

The reason is that whole tables are read to determine the geometry types.

This commit only inspects the first GEOM_TYPE_SELECT_LIMIT rows

Fixes #39897
  • Loading branch information
tomtor committed Nov 16, 2020
1 parent e0574c9 commit 3fba3ff0a70280ff9e3c8c928a863ff292c0d375
Showing with 17 additions and 1 deletion.
  1. +17 −1 src/providers/postgres/qgspostgresconn.cpp
@@ -1911,6 +1911,11 @@ void QgsPostgresConn::retrieveLayerTypes( QVector<QgsPostgresLayerProperty *> &l
QgsWkbTypes::Type type = layerProperty.types.value( 0, QgsWkbTypes::Unknown );
if ( type == QgsWkbTypes::Unknown )
{
// Note that we would like to apply a "LIMIT GEOM_TYPE_SELECT_LIMIT"
// here, so that the previous "array_agg(DISTINCT" does not scan the
// full table. However SQL does not allow that.
// So we have to do a subselect on the table to add the LIMIT,
// see comment in the following code.
sql += QStringLiteral( "UPPER(geometrytype(%1%2))" )
.arg( quotedIdentifier( layerProperty.geometryColName ),
castToGeometry ? "::geometry" : "" );
@@ -1924,7 +1929,18 @@ void QgsPostgresConn::retrieveLayerTypes( QVector<QgsPostgresLayerProperty *> &l

sql += QLatin1String( ") " );

sql += " FROM " + table;
if ( type == QgsWkbTypes::Unknown )
{
// Subselect to limit the "array_agg(DISTINCT", see previous comment.
sql += QStringLiteral( " FROM (SELECT %1 from %2 LIMIT %3) as _unused" )
.arg( quotedIdentifier( layerProperty.geometryColName ) )
.arg( table )
.arg( GEOM_TYPE_SELECT_LIMIT );
}
else
{
sql += " FROM " + table;
}

QgsDebugMsgLevel( "Geometry types,srids and dims query: " + sql, 2 );

0 comments on commit 3fba3ff

Please sign in to comment.
You can’t perform that action at this time.