Самый быстрый способ рассчитать расстояния между двумя координатами? - PullRequest
0 голосов
/ 15 марта 2019

В настоящее время мы используем тип Geography для вычисления расстояния между текущим местоположением и координатами в нашей таблице tsql. Наш код основан на этом sqlauthority.com примере.

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

1 Ответ

0 голосов
/ 15 марта 2019

После тестирования на расстоянии, которое я знаю, зацикливание 100 раз для каждого пакета и запуск пакета 15 раз, чтобы убедиться, что 10 запусков хранилищ статистики клиента в SSMS циклически повторяются после первоначальной генерации плана запроса, поэтому он не искажает результаты , Вот средние из оставшихся. Метод расчета, кажется, в два раза быстрее, чем вариант географии.

С разницей в расстоянии, возвращенной 0,0000000020044.

results

Использован сценарий расчета (возвращено миль: 41,9013152732833)

set nocount on;
declare 
     @lat1 float = 45.489614
    ,@lon1 float = -122.650021
    ,@lat2 float = 44.94404
    ,@lon2 float = -123.025739
select 3959.1825574 * acos(sin(@lat1/57.295779513082323) * sin(@lat2/57.295779513082323) + cos(@lat1/57.295779513082323) * cos(@lat2/57.295779513082323) * cos((@lon2-@lon1)/57.295779513082323)) distance_in_miles
GO 100

Использован сценарий географии (возвращено миль: 41,9013152752877)

set nocount on;
declare
     @g geography = geography::Point(45.489614, -122.650021, 4326)
    ,@h geography = geography::Point(44.94404, -123.025739, 4326)
select @h.STDistance(@g) / 1609.344 distance_in_miles -- 1609.344 is meters in mile. STDistance = meters.
GO 100

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

Вот пример необработанного вычисления .

Рабочий пример встроенного синтаксиса для миль. Это самый простой, точный и короткий синтаксис, который я мог найти.

с поправкой на точность

if object_id('tempdb..#LatLongInfo','U') is not null
    begin
        drop table #LatLongInfo;
    end;
create table #LatLongInfo (
    lat1 float,
    lon1 float,
    lat2 float,
    lon2 float
);
insert into #LatLongInfo
values (21, -76, 23, -72);

select 
    3959.1825574 * acos(sin(lat1/57.295779513082323) * sin(lat2/57.295779513082323) + cos(lat1/57.295779513082323) * cos(lat2/57.295779513082323) * cos((lon2-lon1)/57.295779513082323)) distance_in_miles
from #LatLongInfo;

Надеюсь, это поможет. Я использовал что-то вроде этого, чтобы найти врачей в заданном диапазоне для пациентов, когда был выпущен sql2000, это было давно. Гугл был новорожденным, без карт, ничего кроме окна поиска и одной кнопки. У меня теперь у меня вся ностальгия ... Я помню, как читал это , когда я кодировал это в первый раз.

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