2010-10-22 3 views
3

У меня есть две таблицы, одна из которых называется Point, а другая, называемая Poly i, содержит около 400 полигонов в таблице Poly и около 200 тысяч точек в таблице точек. я хотел найти количество точек в определенном полигоне. Запрос я использую это:SQL Slow Spatial Data

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

Я также создал пространственные индексы на обеих GeoPoint и Poly столбцов и оба столбца географии типа.

Edit: Использование SQL Server 2008

Вопрос: Выше запрос возвращает результаты в около 1 мин до 40 секунд, что является слишком медленным для моего случая, потому что я хотел показать их на Google Maps на реальное время. Является ли мой подход к этой проблеме правильным? или это лучший способ добиться этого?

+0

Какой двигатель базы данных? –

+0

Кажется, это SQL Server 2008 – SQLDev

+0

О, я думал о PostGIS, но я думаю, что это будет ST_Intersects, а не STIntersects. –

ответ

2

Сначала проверьте свои пространственные индексы. Вы можете создать их, используя инструкцию SQL, такую ​​как

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) 

Ключевым параметром для изменения является BOUNDING_BOX. Это может быть установлено в ограничительную рамку ваших данных или максимальную ограничительную рамку ожидаемых данных. Поэтому, если ваши данные ограничены Северной Америкой, установите ограничительную рамку в пределах Северной Америки, а не мира.

Вы можете добавить вычисленные поля, чтобы показать границы каждой функции, как указано в http://geographika.co.uk/sql-server-spatial-sql, - и затем можете использовать стандартный запрос, чтобы увидеть максимальные экстенты.

Также проверьте с помощью профилировщика, чтобы убедиться, что индексы фактически используются. Иногда вам приходится принудительно использовать их с инструкцией WITH (INDEX (MyIndexName)).

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

Я также обнаружил, что иногда это происходит быстрее, если запрос по точкам не использовать пространственный индекс, так что стоит экспериментировать.

Альтернативы

Окончательный вариант должен был бы создать триггер, когда добавляется новая запись, что бы присвоить ему многоугольник идентификатор, когда он будет создан или обновлен. Это позволит почти мгновенные запросы на ваши данные.

И наконец

в последней версии SQL Server Denali пространственных индексов могут быть созданы с помощью автоматической опции, а не вручную. По-видимому, также было повышение производительности для STWithin и STIntersects.

+0

Хмм, я проверю, используется ли индекс. Кстати, тип геометрии быстрее географии? мои столбцы имеют тип географии. –

+0

Тип геометрии использовался только так, как это было в моем примере - вы можете заменить географией – geographika

+0

Я пробовал использовать индекс, но все же он медленный.никакого эффекта не было видно на performace. btw будет использовать соединение между полигоном и таблицей точек. Будет ли на нем работать индекс? –