Помогите с вопросом скорости и производительности SQL-запросов - PullRequest
0 голосов
/ 26 сентября 2011

У меня есть сайт со списком классифицированных автомобилей, который я сейчас разрабатываю на PHP.Пользователь вводит информацию об автомобиле, который он ищет, используя выпадающие списки на главной странице.Когда они нажимают кнопку «Отправить», они попадают на страницу результатов, и у меня возникают проблемы.

На данный момент он настроен следующим образом:

  1. База данных запрашивается для любых результатов, соответствующих автомобилю, который они ищут.Запрос возвращает идентификатор автомобиля и почтовый индекс объявления;
  2. Затем каждое объявление проверяется на расстояние между почтовым индексом пользователя и почтовым индексом объявления.Это само по себе требует запроса к базе данных, чтобы найти координаты для отдельных почтовых индексов каждого рекламного объявления, и занимает довольно много времени для того, что может превышать 350 результатов за раз;
  3. Затем используется оператор if, чтобы определить, является ли расстояниеменьше или равно расстоянию, которое пользователь ввел на главной странице
  4. Если объявление находится в пределах допустимого расстояния, его идентификатор добавляется в массив;
  5. Общее количество объявлений в массиве.затем вычисляется и используется для определения переменной, зависящей от количества рекламных объявлений и количества рекламных объявлений, отображаемых на странице;
  6. Затем выполняется второй запрос таблицы объявлений с использованием оператора WHERE иидентификаторы в массиве.Например, SELECT * FROM adverts WHERE ID=1 AND ID=4 AND ID=23 ........ Общее количество идентификаторов, используемых в запросе, зависит от переменной, указанной в пункте 5. Когда пользователь нажимает на следующую страницу, запрос перезапускается с позиции в массиве,он был оставлен в, а затем запрос был заново создан и выполнен.

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

Изначально планировалось, что запрос будет выполняться с предложениями WHERE для каждого из требований пользователя к автомобилю, а затем перед выводом на страницу проверяется расстояние с помощью оператора if.Это вызвало проблемы с нумерацией страниц, поскольку было невозможно определить количество рекламных объявлений, которые бы соответствовали требованиям к расстоянию от объявлений, возвращаемых в запросе, - следовательно, это делается таким образом, что условия расстояния выполняются до того, как будут собраны полные объявления, поэтомувычисляется точное количество отображаемой рекламы.

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

Спасибо за любые предложения, которые вы можете сделать.

Кто-то запросил макет таблицы и SQL.Здесь идет .....

Таблица объявлений

ID, Марка, Модель, Цвет, Пробег, Двигатель, Год, Почтовый индекс

Таблица почтовых индексов

ID, почтовый индекс, GridN, GridE, долгота, широта

SQL для первого запроса для получения идентификатора и почтового индекса

SELECT ID, Postcode FROM adverts WHERE Make = '$subMake' AND Model = '$subModel' и т. Д.

SQLдля второго запроса, чтобы получить информацию об объявлении, используя идентификаторы, которые соответствуют требованиям к расстоянию:

SELECT Make, Model, Year, Engine, Colour FROM adverts WHERE ID IN(1,2,6,90,112,898)

(Извините, если синтаксически неверно, это работает, что SQL является лишь приблизительным наброском из многих строкстрок запроса.)

Ответы [ 4 ]

0 голосов
/ 26 сентября 2011

В зависимости от вашей базы данных возможно использовать что-то вроде PostGIS?

Установите столбец в таблице Adverts для типа данных LonLat, а затем запустите встроенные функции, такие как ST_DWithin, чтобы найти все объявления с LonLat на указанном расстоянии от целевой записи.

Просто чтобы указать на еще одну проблему, которую я нахожу при использовании статической базы данных почтовых индексов, это то, что они быстро устаревают (особенно для новых сборок). Возможно, вы также захотите использовать что-то вроде Mapstraction, чтобы вернуть геокодированный результат из Google / Yahoo и т. Д. И вместо этого сохранить этот LonLat - хотя вам может потребоваться дополнительная проверка ошибок при вводе почтового индекса и ограничение ваших возвращаемых результатов до точных совпадений.

0 голосов
/ 26 сентября 2011

Самая большая оптимизация - это запрос таблицы почтовых индексов и сохранение ссылок на таблицы в таблице объявлений - при вставке строки рекламы.

Это значительно сократит количество обращений к таблице почтовых индексов..

Вы также можете уменьшить количество вычислений с помощью простой фильтрации таблицы объявлений следующим образом.

Получить значения Users GridN и GridE из таблицы почтовых индексов.Рассчитайте minN как GridN - maxDistance, maxN как GridN + maxDistance, minE как GridE - maxDistance и maxE как GridE + Maxdistance.

Затем можно запросить таблицу объявлений следующим образом:

SELECT * FROM ADVERTS WHERE GridN between (minN,maxN) and GridE Between(minE,maxE);

Чтобы еще больше ускорить это, вы можете добавить индексы к GridN и GridE.

После того, как вы выбрали строки, вы можете рассчитать «реальное» расстояние и отклонить несколько строк, которые выходят за пределы.

0 голосов
/ 26 сентября 2011

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

В дополнение к этому, если вы предоставляете фиксированные параметры (большинство этих веб-сайтов предлагают только 5, 10, 25, 50, 100 в качестве параметров расстояния), то вы можете предварительно рассчитать эти вычисления расстояния и пойти еще дальше.Вы можете выполнить дополнительную проверку и сопоставить каждый почтовый индекс со всеми близлежащими, если вы действительно хотите, вам нужно будет только рассчитать его 5 раз (5 расстояний) для каждого почтового индекса, и вы можете исключить результаты из предыдущего значения, так чтоВы исключаете 5 км из запроса 10 км, потому что вы просто ищете расстояние <= 10 км. </p>

0 голосов
/ 26 сентября 2011

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

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