-
-
Notifications
You must be signed in to change notification settings - Fork 405
Support WFS Paging at database level for MSSQL Driver #5842
Description
Database Paging
WFS requests support a STARTINDEX parameter which allows results to be paged through in conjunction with MAXFEATURES.
A sample request would look as follows:
mapserv -nh "QUERY_STRING=map=test.map&service=WFS&version=2.0.0&request=GetFeature&typeName=MyLayer&outputFormat=geojson&sortBy=Property1%20ASC&startIndex=0&count=20"
The PostGIS driver supports paging at the database level. Other drivers fetch all the results and then MapServer carries out the paging in mapquery.c. Supporting drivers implement layer->vtable->LayerGetPaging.
Allowing WFS Paging at database level for the MSSQL Driver would greatly improve performance when paging through results.
MS SQL 2012+ can simulate paging in SQL with OFFSET and FETCH. A fallback for older versions (and for Azure hosted SQL Server) is RowNumber. The latter approach may be prereable as it is more universal.
Performance Issues
The lack of paging causes a huge overhead and performance hit when providing &startIndex=0&count=20. The database runs the full SQL query for the layer (with no paging) 3 times when running a WFS 2.0.0 GetFeature request:
-
In mapwfs.c with the
msWFSRetrieveFeaturesfunction (and thenmsLayerWhichShapesinmapquery.c(with no paging so the full query is run). -
In mapwfs.c -
msWFSComputeMatchingFeatureswhich again callsmsWFSRetrieveFeaturesand thenLayerDefaultGetShapeCountinmaplayer.cwhich runs the full query again.
The MSSQL has the LayerGetShapeCount set to use the default rather than a database optimisedSELECT COUNT(*) FROM.... This function does exist however in the driver as msMSSQL2008LayerGetNumFeatures and is set to:layer->vtable->LayerGetNumFeatures
Could this be used rather than LayerDefaultGetShapeCount?
- Finally the query is reissued in msMSSQL2008LayerGetShape.
msOGRWriteFromQueryinmapogroutputcallsmsLayerGetShapewhich then due to the following in the MSSQL driver causes another full query:
// variables are as follows
// resultindex = 0
// layerinfo->row_num = 6607 // all features in table
if( resultindex < layerinfo->row_num) {
/* re-issue the query */
SQL Profiler for a single GetFeature request below:
