tags:

views:

49

answers:

1

I have two tables one called Point and other called Poly i have around 400 polygons in the Poly table and around 200 thousand points in Point table. what i wanted is to find how many points are there in a certain polygon. The query i am using is:

select COUNT(*) from point p
inner join Poly pl  on pl.GeoDataID = 101 and p.geopoint.STIntersects(pl.Poly)=1 

I have also created Spatial Indexes on both GeoPoint and Poly Columns and both columns are geography type.

Edit:Using SQL Server 2008

Question: Above query returns results in around 1 min to 40 secs that is too slow for my case because i wanted to show them on Google Maps on real time. Is my approach for this problem is right? or it there any better way to achieve this?

+1  A: 

First check your spatial indexes. You can create them using a SQL statement such as

CREATE SPATIAL INDEX MyIndexName ON MyTable(GeomFieldName) USING GEOMETRY_GRID
WITH (
BOUNDING_BOX =(-1493907.5664457313, 6128509.51667404, -578861.3521250226, 7703103.135644257),
GRIDS =(LEVEL_1 = MEDIUM,LEVEL_2 = MEDIUM,LEVEL_3 = MEDIUM,LEVEL_4 = MEDIUM),
CELLS_PER_OBJECT = 16, PAD_INDEX  = OFF, SORT_IN_TEMPDB = OFF,
DROP_EXISTING = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON)

A key parameter to change is the BOUNDING_BOX. This sould be set to the bounding box of your data, or maximum bounding box of expected data. So if your data is restricted to North America, set the bounding box to the extent of North America rather than the world.

You can add calculated fields to show the bound of each feature as noted at http://geographika.co.uk/sql-server-spatial-sql - and can then use a standard query to see the maximum extents.

Also check using profiler to see that the indexes are actually being used. Sometimes you have to force their use with the WITH (INDEX (MyIndexName)) statement.

SELECT *
FROM MyTable
WITH (INDEX (MyIndexName))
WHERE (geometry::Point(@x,@y,3785).STWithin(MyGeomField) = 1)

I have also found that sometimes it is quicker when querying by points not to use a spatial index, so it is worth experimenting.

Alternatives

A final option would be to create a trigger when a new record is added that would assign it a polygon ID when it is created or updated. This would allow almost instant queries on your data.

geographika
hmm i'll check if index is being used.. btw is geometry type is faster than geography? my columns are of Geography type.
Shoaib Shaikh
Geometry type was only used as that is the example I had - you can replace with geography
geographika
i have tried using index but still it is slow. no effect has been seen on performace. btw will be using join between polygon and point table.. will explicit index work on it?
Shoaib Shaikh
It would be useful to post a screenshot of your Execution Plan for the query (in SQL Management Studio select the option under the Query menu)
geographika
This my orignal query plan. Listing Table relates to Point while GeoData Related to Polygon. http://www.4shared.com/file/9MqHVX-v/execPlan.html
Shoaib Shaikh
Did you try with the STWithin rather than STIntersects?
geographika
STWithin is quite slower than STIntersects. It takes around 2 min and 20 secs while STIntersects takes only around 48 secs.
Shoaib Shaikh
One more thing i noticed is if i use a where clause to specify bounding box for the area it helps alot and gives result in almost in half of the time. [where (l.Latitude > 47.4 AND l.Latitude < 47.5 and l.Longitude > -122.4 and l.Longitude < -122.3)]
Shoaib Shaikh
If tghat is the case then you need to better tune your spatial index. What parameters did you use to build it? Is your data worldwide?
geographika