Skip to content

Commit

Permalink
Use IN (...) for postgres FilterFids requests when the primary
Browse files Browse the repository at this point in the history
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
  • Loading branch information
nyalldawson committed Nov 5, 2015
1 parent 8c86aab commit 7964772
Showing 1 changed file with 27 additions and 5 deletions.
32 changes: 27 additions & 5 deletions src/providers/postgres/qgspostgresprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -549,13 +549,35 @@ QString QgsPostgresUtils::whereClause( QgsFeatureId featureId, const QgsFields&

QString QgsPostgresUtils::whereClause( const QgsFeatureIds& featureIds, const QgsFields& fields, QgsPostgresConn* conn, QgsPostgresPrimaryKeyType pkType, const QList<int>& pkAttrs, QSharedPointer<QgsPostgresSharedData> sharedData )
{
QStringList whereClauses;
Q_FOREACH ( const QgsFeatureId featureId, featureIds )
switch ( pkType )
{
whereClauses << whereClause( featureId, fields, conn, pkType, pkAttrs, sharedData );
}
case pktOid:
case pktInt:
{
//simple primary key, so prefer to use an "IN (...)" query. These are much faster then multiple chained ...OR... clauses
QString delim;
QString expr = QString( "%1 IN (" ).arg(( pkType == pktOid ? "oid" : QgsPostgresConn::quotedIdentifier( fields[ pkAttrs[0] ].name() ) ) );

return whereClauses.isEmpty() ? "" : whereClauses.join( " OR " ).prepend( '(' ).append( ')' );
Q_FOREACH ( const QgsFeatureId featureId, featureIds )
{
expr += delim + QString::number( featureId );
delim = ',';
}
expr += ')';

return expr;
}
default:
{
//complex primary key, need to build up where string
QStringList whereClauses;
Q_FOREACH ( const QgsFeatureId featureId, featureIds )
{
whereClauses << whereClause( featureId, fields, conn, pkType, pkAttrs, sharedData );
}
return whereClauses.isEmpty() ? "" : whereClauses.join( " OR " ).prepend( '(' ).append( ')' );
}
}
}

QString QgsPostgresUtils::andWhereClauses( const QString& c1, const QString& c2 )
Expand Down

0 comments on commit 7964772

Please sign in to comment.