Skip to content

Commit 14408d3

Browse files
committed
Use IN (...) for postgres FilterFids requests when the primary
key is a simple (non compound) type IN (...) is much faster than chained ...OR... clauses Additionally, trying to filter by a large number of feature Ids (eg > 30k ) fails when using the ...OR... approach, but works using IN
1 parent ce2a84d commit 14408d3

File tree

1 file changed

+27
-5
lines changed

1 file changed

+27
-5
lines changed

src/providers/postgres/qgspostgresprovider.cpp

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -549,13 +549,35 @@ QString QgsPostgresUtils::whereClause( QgsFeatureId featureId, const QgsFields&
549549

550550
QString QgsPostgresUtils::whereClause( QgsFeatureIds featureIds, const QgsFields& fields, QgsPostgresConn* conn, QgsPostgresPrimaryKeyType pkType, const QList<int>& pkAttrs, QSharedPointer<QgsPostgresSharedData> sharedData )
551551
{
552-
QStringList whereClauses;
553-
Q_FOREACH ( const QgsFeatureId featureId, featureIds )
552+
switch ( pkType )
554553
{
555-
whereClauses << whereClause( featureId, fields, conn, pkType, pkAttrs, sharedData );
556-
}
554+
case pktOid:
555+
case pktInt:
556+
{
557+
//simple primary key, so prefer to use an "IN (...)" query. These are much faster then multiple chained ...OR... clauses
558+
QString delim;
559+
QString expr = QString( "%1 IN (" ).arg(( pkType == pktOid ? "oid" : QgsPostgresConn::quotedIdentifier( fields[ pkAttrs[0] ].name() ) ) );
560+
561+
Q_FOREACH ( const QgsFeatureId featureId, featureIds )
562+
{
563+
expr += delim + QString::number( featureId );
564+
delim = ',';
565+
}
566+
expr += ')';
557567

558-
return whereClauses.isEmpty() ? "" : whereClauses.join( " OR " ).prepend( "(" ).append( ")" );
568+
return expr;
569+
}
570+
default:
571+
{
572+
//complex primary key, need to build up where string
573+
QStringList whereClauses;
574+
Q_FOREACH ( const QgsFeatureId featureId, featureIds )
575+
{
576+
whereClauses << whereClause( featureId, fields, conn, pkType, pkAttrs, sharedData );
577+
}
578+
return whereClauses.isEmpty() ? "" : whereClauses.join( " OR " ).prepend( '(' ).append( ')' );
579+
}
580+
}
559581
}
560582

561583
QString QgsPostgresUtils::andWhereClauses( const QString& c1, const QString& c2 )

0 commit comments

Comments
 (0)