SQL Server География

Есть ли возможный способ улучшить запрос ниже:

DECLARE @radiusInMeters FLOAT = 400;
DECLARE @dgeog geography = geography::Point(given_latitude, given_longitude, 4326).STBuffer(@radiusInMeters);

select [fdx].latitude, [fdx].longitude
from [dbo].[fdx]
where @dgeog.STIntersects(geography::STGeomFromText('POINT(' + convert(varchar(20), [fdx].longitude) + ' ' + convert(varchar(20), [fdx].latitude) + ')', 4326)
                         ) = 1

2 ответа

Решение

kcung и Hasan BINBOGA верны, вам нужен пространственный индекс.

Посмотрите на ваш запрос: @dgeog.STIntersects(xxxx) = 1 Для этого требуется, чтобы [xxxx] был типом данных географии. Чтобы [xxxx] был типом данных географии, к строке должна быть применена функция STGeomFromText. И поскольку это единственная часть предложения WHERE, функция должна применяться ко всем строкам.

Если таблица fdx особенно велика, это означает, что функцию CLR придется применять снова и снова. Это не (в терминах SQL-Server) быстрый процесс.

Попробуйте это, если можете:

ALTER dbo.fdx ADD Point AS (GEOGRAPHY::Point(Latitude, Longitude, 4326)) PERSISTED
GO
CREATE SPATIAL INDEX SIndex_FDX ON dbo.fdx (Point) 
USING GEOGRAPHY_GRID
WITH (
  GRIDS = (LEVEL_1 = HIGH,LEVEL_2 = HIGH,LEVEL_3 = HIGH,LEVEL_4 = HIGH), 
  CELLS_PER_OBJECT = 1
)
GO
DECLARE @Latitude DECIMAL(15,10) = 0
DECLARE @Longitude DECIMAL(15,10) = 0
DECLARE @Radius FLOAT = 400
DECLARE @g GEOGRAPHY = GEOGRAPHY::Point(@Latitude, @Longitude, 4326).STBuffer(@Radius)
SELECT * FROM dbo.fdx WHERE Point.STIntersects(@g) = 1

Примечание. Вам следует преобразовать свои пары широта / долгота в десятичные числа, прежде чем использовать их для вычисления столбца географии. Существует неявное преобразование из числа с плавающей точкой в ​​десятичную строку, когда вы используете в качестве входных данных число с плавающей точкой, которое урезает ваши координаты до 4 десятичных знаков. Если вы сначала конвертируете явно, это не будет проблемой.

Кроме того, если у вас есть какие-либо значения null lat / long в dbo.fdx, вам нужно отфильтровать их в предложении WHERE, поскольку нулевое значение приведет к тому, что ваш пространственный индекс не будет работать должным образом.

Вы можете создать пространственный индекс: https://msdn.microsoft.com/en-us/library/bb934196.aspx

Другие вопросы по тегам