Большой набор данных (от SQL до C #), исправление долгого времени загрузки - PullRequest
3 голосов
/ 25 марта 2009

У меня есть сайт, который я создаю, это приложение, которое создает почтовые слияния (более или менее ...) на основе нескольких пользовательских предпочтений. Он может без проблем генерировать данные в виде декартовых объединений, но приходит потребность предприятия сделать жизнь немного сложнее ...

Мне нужно создать приложение, чтобы после проверки почтовых индексов удаленных сотрудников оно создавало электронные письма для целевых объектов мультимедиа на основе того, насколько далеко от этого сотрудника находится целевое значение мультимедиа. Скажем, например, сотрудники являются хорошо известными добровольцами, где они работают. Предприятие хочет отправить по электронной почте в радиусе 5 миль от этих сотрудников сообщение о работе, которую выполняет сотрудник. Вот где все становится не так ... У меня есть несколько вариантов, которые я опишу попытки и неудачи:

  1. Наибольший радиус составляет 20 миль. Я создаю таблицу базы данных, в которой хранятся записи каждого почтового индекса в США, соединенные с каждым почтовым индексом в пределах 20 миль от этого почтового индекса. Набор данных выглядит примерно так (Имена разные, это ради аргумента):
    [SourceZip] | [Город] | [Государство] | [CloseZip] | [Город] | [Государство] | [Distance]
    Сбои: Например, в Нью-Йорке есть 350 тыс. Записей из вышеуказанного набора данных (а другие штаты хуже!). Среднее время загрузки на этой странице? 6 минут ... не происходит. Я проверил это, установив точки останова, именно на этапе dataadapter.fill () происходит отключение.

  2. (Этот никогда не был реализован из-за проблем с логистикой) Я устанавливаю соединение с базой данных для каждого почтового индекса сотрудника на целевые почтовые индексы с расстоянием х или меньше. За исключением того, что исходные файлы и целевые медиа-объекты могут объединять до 34 тысяч индивидуальных писем. 34 КБ подключений? даже если бы я смог придумать способ повторного поиска по почтовому индексу, я провел несколько тестовых проверок в БД и обнаружил, что в Нью-Йорке есть 500 различных почтовых индексов, где работали сотрудники. 500 дБ подключений? Я сомневаюсь, что это сработает, но я могу быть удивлен.

  3. Моя последняя схема, позволяющая обойти эту проблему, заключается в том, что, надеясь, что веб-сервер запускает лучшую игру, чем объект набора данных .net, получая новый набор данных, выглядит следующим образом:
    [zip] | [долгота] | [Широта]
    Затем выполните формулу расстояния, чтобы выяснить, работают ли данные. Это сильно зависит от процессоров на веб-сервере. Является ли это выгодной игрой, или я найду такой же урон во время загрузки в этой попытке?

    Есть ли лучший способ?

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

Дополнительные примечания : У меня нет контроля над сервером, и я использую SQL2k :(. Я программирую сайт в Visual Studio 2005, framework 2.0. Может быть обновлен до SQL2005 и VS2008 в течение следующих нескольких месяцев.

Ответы [ 5 ]

2 голосов
/ 25 марта 2009

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

Это очень хорошо работает в веб-приложениях со всеми данными почтового индекса США.

Запрос будет выглядеть примерно так:

select * from zip where 
   dbo.udf_Haversine(zip.lat,zip.long, @lat, @lon) < 20   -- (miles)

Вы не применили бы это к адресу каждого получателя, но сначала вы должны определить почтовые индексы в пределах своего радиуса (во вложенном запросе или с CTE), а затем присоединиться ко всем адресам, которые необходимы для отправки почты. к.

1 голос
/ 25 марта 2009

Если у вас есть набор данных для ваших сотрудников, набор данных для ваших носителей и третий набор данных для расстояния между исходным и целевым почтовыми индексами, вы можете сэкономить немного времени, соединяя 3 таблицы вместе ...

SELECT *
FROM Employees_List
   INNER JOIN 
       (Media_List INNER JOIN Distance_List ON Media_List.Zip = Distance_List.Target_Zip)
   ON Employees_List.Zip = Distance_List.Source_Zip
WHERE distance_Miles <=5

Таким образом вы устанавливаете отношения между Сотрудником и СМИ, используя Расстояние.

0 голосов
/ 26 марта 2009

ВЫБОР 350K строк (ваш пример для Нью-Йорка) не займет 6 минут, если вы упорядочите таблицу и индекс по SOURCEZIP (ALTER TABLE .. ORDER BY (SOURCEZIP)) в MySQL. Это займет всего лишь долю секунды ... ALTER займет много времени (или вы можете создать таблицу в таком порядке) - но поскольку это статическая таблица, она ничего не стоит.

0 голосов
/ 25 марта 2009

РЕДАКТИРОВАТЬ После исследования ответ с функцией Haversine - это маршрут, который я бы выбрал ... он не такой интенсивный, как функция, используемая нашей БД (которая будет исправлена:))

Вы должны , а не вычислять расстояния каждый раз, это тяжелый расчет от длинного / широты до длинного / широты, и если вы делаете это более одного раза, это не нужно.

При этом я не уверен, почему вы уже списали вариант №2. Мы на самом деле делаем что-то похожее на это. Возможно, меня смущают цифры, но то, о чем вы говорите, не должно вызывать у SQL2k ничего.

Даже если вы вычислите в автономном режиме расстояние от zip до zip в США, строк будет всего ~ 2 млрд. Да, это много, но оно очень статично, может быть повреждено, если оно медленное и т. Д.

0 голосов
/ 25 марта 2009

Вы используете SQL 2008? Если это так, новые пространственные данные могут быть именно тем, что вы ищете здесь. Вы можете найти координаты в пределах диапазона другого так же легко, как с помощью сравнения "LIKE" для строк.

http://www.microsoft.com/sqlserver/2008/en/us/spatial-data.aspx

...