Today me and the SQL Server DataStore plugin spent some quality time together. 
And we definitely had some fun! :-)  Here’s an overview of my discoveries. All 
these tests are executed using a SQL Server 2008 R2 and the SQL Server 
DataStore 13.x version. I can’t perform similar tests against another version 
of SQL Server fort he simple reason I don’t have one available :-)


First of all I looked why the “enforcing spatial index” hint isn’t added.to the 
query. The code verifies if spatial attributes are used in the filter. If it 
is, then the occurences for each spatial attribute in the filter are counted. 
Only if there’s one spatial attribute which occurs just once in the filter, the 
“enforcing spatial index” hint is added to the query. This is the appropriate 
code snippet from SQLServerDialect.getSpatialIndexes:
// we can only apply one index on one condition
if(attribute.getValue() > 1) {
      continue;
}


Then I looked at the performance issue we are experiencing. So to render our 
(OpenLayers) map 15 GetMap-requests are sent to GeoServer and for every tile 
the data of 13 layers (tables) is required. Each request has a CQL_FILTER with 
an Intersects. I always used the same scenario to compare the results and it’s 
pretty simple: rendering a map on a few different zoom levels. I’ll only focus 
on the lowest zoom leve here, because performance is the worst at this zoom 
level. I used SQL Server Profiler to gather all sql query related information.

1. Using the original sql server plugin

Using the original sql server plugin, this kind of query is generated and 
executed:
SELECT "uid","node_type","owner","geom".STAsBinary() as "geom"
FROM "dbo"."spatial_node"
WHERE  ("geom".Filter(geometry::STGeomFromText('POLYGON ((155859.87158203 
202811.63085938, 155859.87158203 203077.25537109, 156125.49609375 
203077.25537109, 156125.49609375 202811.63085938, 155859.87158203 
202811.63085938))', 31370)) = 1
AND "geom".STIntersects(geometry::STGeomFromText('POLYGON ((155859.87158203 
202811.63085938, 155859.87158203 203077.25537109, 156125.49609375 
203077.25537109, 156125.49609375 202811.63085938, 155859.87158203 
202811.63085938))', 31370)) = 1
AND "geom".Filter(geometry::STGeomFromText('POLYGON ((155854.164805411 
202805.92408276122, 155854.164805411 203082.96214770878, 156131.202870369 
203082.96214770878, 156131.202870369 202805.92408276122, 155854.164805411 
202805.92408276122))', 31370)) = 1)

So in the WHERE clause you have 3 spatial functions: one Filter and one 
STIntersects (from the CQL_FILTER parameter); and another Filter (from the BBOX 
parameter). Each of these queries take up to 250-300ms. And the average time to 
execute a GetMap-request (at this zoom level) is 3450ms.


2. Only STIntersects (CQL_FILTER) and Filter (BBOX)

For this test, I changed the sql server plugin so that it only generates a 
STIntersects (from the CQL_FILTER parameter) and a Filter (from the BBOX 
parameter). The query that’s generated and executed looks like:
SELECT "uid","node_type","owner","geom".STAsBinary() as "geom"
FROM "dbo"."spatial_node"
WHERE  ("geom".STIntersects(geometry::STGeomFromText('POLYGON ((155859.87158203 
202811.63085938, 155859.87158203 203077.25537109, 156125.49609375 
203077.25537109, 156125.49609375 202811.63085938, 155859.87158203 
202811.63085938))', 31370)) = 1
AND "geom".Filter(geometry::STGeomFromText('POLYGON ((155854.164805411 
202805.92408276122, 155854.164805411 203082.96214770878, 156131.202870369 
203082.96214770878, 156131.202870369 202805.92408276122, 155854.164805411 
202805.92408276122))', 31370)) = 1)

So in the WHERE clause you now have only 2 spatial functions. Each of these 
queries execute in 100-200ms! That’s already a huge performance boost. And 
that’s already noticable if you look at the average time to execute a 
GetMap-request (at this zoom level): it takes only 1900ms. So almost 50% faster.


3. Only STIntersects (CQL_FILTER)

At this zoom level the polygon in the CQL_FILTER parameter is almost the same 
as the BBOX polygon (that’s because our application generates the polygon in 
the CQL_FILTER by intersecting the user’s restricted geographical area with the 
BBOX parameter). So the Filter condition (from the BBOX parameter) becomes 
redundant in this case. For this test, I changed the sql server plugin so that 
it only generates a STIntersects (from the CQL_FILTER parameter). The query 
that’s generated and executed looks like:
SELECT "uid","node_type","owner","geom".STAsBinary() as "geom"
FROM "dbo"."spatial_node"
WHERE  ("geom".STIntersects(geometry::STGeomFromText('POLYGON ((152938.00195313 
202811.63085938, 152938.00195313 203874.12890625, 154000.5 203874.12890625, 
154000.5 202811.63085938, 152938.00195313 202811.63085938))', 31370)) = 1
AND 1 = 1)

So in the WHERE clause you now have only 1 spatial function. Each of these 
queries execute in 20-50ms! Which is again a huge performance improvement. 
Needless to say that the average time to execute a GetMap-request (at this zoom 
level) will be less as well: only 1400ms.



Conclusion: so it seems for  SQL Server 2008 R2 it would be a good thing to get 
rid of the additional Filter condition if you have an Intersects in the 
CQL_FILTER (and probably for the other spatial functions as well).


Kind regards,
Roel De Nijs
Senior Java Developer


Van: [email protected] [mailto:[email protected]] Namens Andrea Aime
Verzonden: woensdag 30 september 2015 19:08
Aan: Roel De Nijs <[email protected]>
CC: [email protected]
Onderwerp: Re: [Geoserver-users] GetMap-request with CQL_FILTER too sl

On Wed, Sep 30, 2015 at 7:02 PM, Roel De Nijs 
<[email protected]<mailto:[email protected]>> wrote:
Hi Andrea,

Luckily this issue only affects a very minor group of users. That’s also why 
this issue could be left untouched for half a year. If the majority of our 
users would have been affected, that would never have been possible :-D

In an ideal world, that would be true... in practice an issue is fixed when 
there is someone willing to spend time or funds on it, which does not always 
correlate well with the number of users affected, believe me ;-)

So it seems that when you use a CQL_FILTER there is some kind of additional 
processing of the returned features from the database. And if no features are 
returned, then no additional processing is required (which would explain why 
some of the GetMap requests finish rather quickly). Do these thoughts make any 
sense at all?

I'm not aware of any extra processing. But beware, running queries manually and 
via JDBC can sometimes lead to very different
results. Especially when done like GeoServer does, but setting a fetch size to 
avoid getting millions of records on the client
side in a single shot and going OOM as a result

Cheers
Andrea

--
==
GeoServer Professional Services from the experts! Visit
http://goo.gl/it488V for more information.
==

Ing. Andrea Aime
@geowolf
Technical Lead

GeoSolutions S.A.S.
Via Poggio alle Viti 1187
55054  Massarosa (LU)
Italy
phone: +39 0584 962313
fax: +39 0584 1660272
mob: +39  339 8844549

http://www.geo-solutions.it
http://twitter.com/geosolutions_it


AVVERTENZE AI SENSI DEL D.Lgs. 196/2003

Le informazioni contenute in questo messaggio di posta elettronica e/o nel/i 
file/s allegato/i sono da considerarsi strettamente riservate. Il loro utilizzo 
è consentito esclusivamente al destinatario del messaggio, per le finalità 
indicate nel messaggio stesso. Qualora riceviate questo messaggio senza esserne 
il destinatario, Vi preghiamo cortesemente di darcene notizia via e-mail e di 
procedere alla distruzione del messaggio stesso, cancellandolo dal Vostro 
sistema. Conservare il messaggio stesso, divulgarlo anche in parte, 
distribuirlo ad altri soggetti, copiarlo, od utilizzarlo per finalità diverse, 
costituisce comportamento contrario ai principi dettati dal D.Lgs. 196/2003.



The information in this message and/or attachments, is intended solely for the 
attention and use of the named addressee(s) and may be confidential or 
proprietary in nature or covered by the provisions of privacy act (Legislative 
Decree June, 30 2003, no.196 - Italy's New Data Protection Code).Any use not in 
accord with its purpose, any disclosure, reproduction, copying, distribution, 
or either dissemination, either whole or partial, is strictly forbidden except 
previous formal approval of the named addressee(s). If you are not the intended 
recipient, please contact immediately the sender by telephone, fax or e-mail 
and delete the information in this message that has been received in error. The 
sender does not give any warranty or accept liability as the content, accuracy 
or completeness of sent messages and accepts no responsibility  for changes 
made after they were sent or for other risks which arise as a result of e-mail 
transmission, viruses, etc.

-------------------------------------------------------

________________________________

Volg Aquafin op Facebook<https://www.facebook.com/AquafinNV> | 
Twitter<https://twitter.com/aquafinnv> | 
YouTube<http://www.youtube.com/channel/UCk_4P5BJ-MtEEDCkCsR_KqQ?feature=mhee> | 
LinkedIN<http://www.linkedin.com/company/aquafin/products>

Disclaimer: zie www.aquafin.be<http://www.aquafin.be>   P Denk aan het milieu. 
Druk deze mail niet onnodig af.

------------------------------------------------------------------------------
_______________________________________________
Geoserver-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/geoserver-users

Reply via email to