Расчет расстояния с огромной базой данных SQL Server - PullRequest
2 голосов
/ 16 декабря 2011

У меня есть огромная база данных предприятий (около 500 000) с почтовым индексом, адресом и т. Д. Мне нужно отображать их в порядке возрастания от 100 миль пользователей почтовый индекс. У меня есть таблица для почтовых индексов с соответствующей широтой и долготой. Что будет быстрее / лучшее решение?

Случай 1: рассчитать расстояние и отсортировать по расстоянию. У меня будет текущий почтовый индекс пользователей, широта и долгота в сессии. Я вычислю расстояние, используя функцию SQL Server.

Случай 2: получить все почтовые индексы в районе 50 миль и получить предприятия со всеми этими почтовыми индексами. Здесь мне придется написать выборку во вложенном запросе при поиске предприятий.

Я думаю, что в случае 1 будет рассчитано расстояние для всех предприятий в базе данных. В то время как 2-й случай будет просто получать почтовые индексы и в конечном итоге будет получать только необходимые предприятия. Следовательно, случай 2 должен быть лучше? Буду признателен за любые предложения здесь.

Вот запрос LINQ, который у меня есть для случая 1.

var businessListQuery = (from b in _DB.Businesses
                         let distance = _DB.CalculateDistance(b.Zipcode,userLattitude,userLogntitude)
                         where b.BusinessCategories.Any(bc => bc.SubCategoryId == subCategoryId)
                                         && distance < 100
                         orderby distance
                         select new BusinessDetails(b, distance.ToString()));

int totalRecords = businessListQuery.Count();
var ret = businessListQuery.ToList().Skip(startRow).Take(pageSize).ToList();

На боковой ноте приложение находится на C #.

Спасибо

1 Ответ

4 голосов
/ 16 декабря 2011

Вы можете сделать хуже, чем посмотреть на тип данных GEOGRAPHY, например:

CREATE TABLE Places
(
    SeqID       INT IDENTITY(1,1),
    Place       NVARCHAR(20),
    Location    GEOGRAPHY
)
GO
INSERT INTO Places (Place, Location) VALUES ('Coventry', geography::Point(52.4167, -1.55, 4326))
INSERT INTO Places (Place, Location) VALUES ('Sheffield', geography::Point(53.3667, -1.5, 4326))
INSERT INTO Places (Place, Location) VALUES ('Penzance', geography::Point(50.1214, -5.5347, 4326))
INSERT INTO Places (Place, Location) VALUES ('Brentwood', geography::Point(52.6208, 0.3033, 4326))
INSERT INTO Places (Place, Location) VALUES ('Inverness', geography::Point(57.4760, -4.2254, 4326))
GO
SELECT p1.Place, p2.place, p1.location.STDistance(p2.location) / 1000 AS DistanceInKilometres
    FROM Places p1
    CROSS JOIN Places p2
GO  
SELECT p1.Place, p2.place, p1.location.STDistance(p2.location) / 1000 AS DistanceInKilometres
    FROM Places p1
        INNER JOIN Places p2 ON p1.SeqID > p2.SeqID
GO  

geography::Point принимает широту и долготу, а также SRID (номер специального справочного номера).В этом случае SRID равен 4326, что является стандартной широтой и долготой.Поскольку у вас уже есть широта и долгота, вы можете просто ALTER TABLE добавить столбец географии, а затем UPDATE, чтобы заполнить его.

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

Обратите внимание, что перекрестное соединение даст вам 250 000 000 000 строк, но поиск прост, поскольку вам нужно только взглянуть на один из столбцов мест (т. Е. SELECT * FROM table WHERE Place1 = 'Sheffield' AND distance < 100, второй даст вам значительно меньше строк, нозапрос должен учитывать столбцы Place1 и Place2).

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