I have one MsSql2008FeatureLayer with 1316 features in it and another with 11013 features.
When I click on the map I use Layer.QueryTools.GetFeaturesInsideBoundingBox to find what feature I have clicked on. It takes about 0.5s for the first layer to return a result and about 2.5-3.0s for the second layer. Is there any way that I can speed this up?
I can’t get it to search only those features that are being displayed or, at least, haven’t figured out how to do that yet. I tried to keep an InMemoryFeatureLayer updated which would contain only the visible features, but it slowed the entire application down.
MsSql2008FeatureLayer QueryTools
Hi Clay,
The 1316 features for a InmemoryFeatureLayer is not heavy but the 11013 should be. If you want to use InMemoryFeatureLayer I think you can try to load all 1316 features to one layer(don’t need to show that on map) when application startup, then you can query on it and this should can save the 0.5s when need to query for this layer.
For MsSql2008FeatureLayer, the GetFeaturesInsideBoundingBox API will create the query string and execute that on database side, so I think maybe you can try to call MsSql2008FeatureLayer.BuildIndex, which should be helpful to improve the spatial query speed on database side.
Regards,
Don
I tried adding the index, but I receive this error message: “Could not create the XML or spatial index on object ‘PremiseWithGeometry’ because that object is not a table. Create the index on the base table column”
This MsSql2008FeatureLayer is created from a view in SQL, not a table. How could I create the index on the base table column?
And even if that doesn’t work, is there a better way to search it?
Hi Clay,
Sorry for delay on this, we cannot build index for a view
through our assembly currently. But I think maybe you can create index for each
table to speed query up, please try that, in my end the speed is fast enough so
I cannot see the performance improve after build index.
I created a view, the corresponding table contains 13861
features, the average time per query is 200 milliseconds. (The test PCs are in same LAN)
Following is the testing code and result:
===Code===
viewLayer.Open();
var boundingbox =
viewLayer.GetBoundingBox();
for (int i = 0; i < 10; i++)
{
Stopwatch
stw = new Stopwatch();
stw.Start();
var features1 =
viewLayer.QueryTools.GetFeaturesInsideBoundingBox(boundingbox, ReturningColumnsType.NoColumns);
stw.Stop();
Debug.WriteLine("before build index" + i + " :
time=" + stw.ElapsedMilliseconds.ToString() + " FeaturesInsideBoundingBox count " + features1.Count);
}
tableLayer.Open();
tableLayer.BuildIndex(BuildIndexMode.Rebuild);
for (int j = 0; j < 10; j++)
{
Stopwatch
stw2 = new Stopwatch();
stw2.Start();
var feaures2 =
viewLayer.QueryTools.GetFeaturesInsideBoundingBox(boundingbox, ReturningColumnsType.NoColumns);
stw2.Stop();
Debug.WriteLine("after build index" + j + " :
time=" + stw2.ElapsedMilliseconds.ToString() + " FeaturesInsideBoundingBox count " + feaures2.Count);
}
===Result===
We should want to make sure which part spend most time in the
entire query process, the possible reasons are in our map logic, networking
delay, database query speed, or map data format.
Because I cannot reproduce that local, so could you please do
a test on your side? You can try to get the SQL statement from the code as
below and then execute it directly in the database. If the execution time is slow,
maybe we should think about how to make the database query faster.
msSql2008FeatureLayer.Open();
MsSql2008FeatureSource featureSource = msSql2008FeatureLayer.FeatureSource as MsSql2008FeatureSource;
featureSource.ExecutingSqlStatement += FeatureSource_ExecutingSqlStatement;
// Using your bounding box.
featureSource.GetFeaturesInsideBoundingBox(new RectangleShape(-10, 10, 10, -10),ReturningColumnsType.NoColumns);
private void
FeatureSource_ExecutingSqlStatement(object sender, ExecutingSqlStatementMsSql2008FeatureSourceEventArgs e)
{
if
(e.ExecutingSqlStatementType == ExecutingSqlStatementType.GetFeaturesInsideBoundingBoxEx)
{
// this is the sql statement.
string
sqlStatement = e.SqlStatement;
}
}
And if that’s not the database reason, if possible could you
please sent your test database to us which should be helpful for reproduce the
issue?
Thanks,