Commit e96b3df0 authored by Fernando Miño's avatar Fernando Miño Committed by Nuno Oliveira
Browse files

[GEOS-9088] OR performance issue with complex subqueries on app-schema with postgis datasource

parent 7426e45f
......@@ -83,3 +83,27 @@ Much like joining support, native encoding of nested filters is turned on by def
Or, alternatively, by setting the value of the Java System Property "app-schema.encodeNestedFilters" to "false", for example ::
java -DGEOSERVER_DATA_DIR=... -Dapp-schema.encodeNestedFilters=false Start
UNION performance improvement for OR conditions
-----------------------------------------------
OR conditions are difficult to optimize for postgresql and are usually slow. App-Schema improves OR condition performance using UNION clauses instead OR for nested filter subqueries.
With UNION improvement enabled main OR binary operator on nested filter subquery will rebuild normal OR query like::
SELECT id, name FROM table WHERE name = "A" OR name = "B"
to::
SELECT id, name FROM table WHERE name = "A" UNION SELECT id, name FROM table WHERE name = "B"
UNION improvement is enabled by default, and it is disabled by adding to your app-schema.properties file the line ::
app-schema.orUnionReplace = false
Or, alternatively, by setting the value of the Java System Property "app-schema.orUnionReplace" to "false", for example ::
java -DGEOSERVER_DATA_DIR=... -Dapp-schema.orUnionReplace=false Start
.. note::
This optimization will only be applied when a PostgresSQL database is being used.
\ No newline at end of file
......@@ -17,6 +17,7 @@ import org.geotools.appschema.filter.FilterFactoryImplNamespaceAware;
import org.geotools.appschema.jdbc.NestedFilterToSQL;
import org.geotools.data.FeatureSource;
import org.geotools.data.complex.AppSchemaDataAccess;
import org.geotools.data.complex.AppSchemaDataAccessRegistry;
import org.geotools.data.complex.FeatureTypeMapping;
import org.geotools.data.complex.filter.ComplexFilterSplitter;
import org.geotools.data.jdbc.FilterToSQLException;
......@@ -534,6 +535,15 @@ public class SimpleAttributeFeatureChainWfsTest extends AbstractAppSchemaTestSup
// "appschematest"."MAPPEDFEATUREWITHNESTEDNAME"."ID" = "chain_link_1"."MF_ID"))
assertTrue(encodedCombined.matches("^\\(.*GUNTHORPE FORMATION.*OR.*EXISTS.*\\)$"));
assertContainsFeatures(fs.getFeatures(combined), "mf1", "mf3");
// test UNION improvement off
AppSchemaDataAccessRegistry.getAppSchemaProperties()
.setProperty("app-schema.orUnionReplace", "false");
try {
assertContainsFeatures(fs.getFeatures(combined), "mf1", "mf3");
} finally {
AppSchemaDataAccessRegistry.getAppSchemaProperties()
.setProperty("app-schema.orUnionReplace", "true");
}
/*
* test filter comparing multiple nested attributes
......@@ -560,6 +570,42 @@ public class SimpleAttributeFeatureChainWfsTest extends AbstractAppSchemaTestSup
assertContainsFeatures(fs.getFeatures(notEquals), "mf1", "mf2", "mf3", "mf4");
}
/** Checks a nested OR condition with UNION improvement on and off */
@Test
public void testUnionImprovement() throws IOException, FilterToSQLException {
FeatureTypeInfo ftInfo = getCatalog().getFeatureTypeByName("gsml", "MappedFeature");
FeatureSource fs = ftInfo.getFeatureSource(new NullProgressListener(), null);
AppSchemaDataAccess da = (AppSchemaDataAccess) fs.getDataStore();
FeatureTypeMapping rootMapping = da.getMappingByNameOrElement(ftInfo.getQualifiedName());
// make sure nested filters encoding is enabled, otherwise skip test
assumeTrue(shouldTestNestedFiltersEncoding(rootMapping));
JDBCDataStore store = (JDBCDataStore) rootMapping.getSource().getDataStore();
NestedFilterToSQL nestedFilterToSQL = createNestedFilterEncoder(rootMapping);
FilterFactoryImplNamespaceAware ff = new FilterFactoryImplNamespaceAware();
ff.setNamepaceContext(rootMapping.getNamespaces());
PropertyIsEqualTo regularFilter =
ff.equals(ff.property("gml:name[2]"), ff.literal("nameone 2"));
PropertyIsEqualTo nestedFilter =
ff.equals(ff.property("gml:name[2]"), ff.literal("nameone 4"));
Or combined = ff.or(regularFilter, nestedFilter);
assertContainsFeatures(fs.getFeatures(combined), "mf2", "mf3");
// set improvement to off
AppSchemaDataAccessRegistry.getAppSchemaProperties()
.setProperty("app-schema.orUnionReplace", "false");
try {
FeatureTypeInfo ftInfo1 = getCatalog().getFeatureTypeByName("gsml", "MappedFeature");
FeatureSource fs1 = ftInfo.getFeatureSource(new NullProgressListener(), null);
assertContainsFeatures(fs1.getFeatures(combined), "mf2", "mf3");
} finally {
AppSchemaDataAccessRegistry.getAppSchemaProperties()
.setProperty("app-schema.orUnionReplace", "true");
}
}
private void checkMf1(Document doc) {
assertXpathCount(4, "//gsml:MappedFeature[@gml:id='gsml.mappedfeature.mf1']/gml:name", doc);
// gml:name with values coming from the main table
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment