PHP / MySQL Выполнение поиска, связанного с расстоянием, без использования HAVING - PullRequest
1 голос
/ 09 сентября 2011

У меня есть запрос, который работает нормально, но он немного медленный.После небольшого исследования я обнаружил, что использование части моего запроса HAVING вызывает замедление.Есть ли способ сделать это БЕЗ использования части HAVING?

$query = sprintf("SELECT p.*,( 3959 * acos( cos( radians('%s') ) *
   cos( radians( `loclat` ) ) * cos( radians( `loclong` ) - radians('%s') ) 
   + sin( radians('%s') ) * sin( radians( `loclat` ) ) ) ) AS distance
     FROM postLocation as pl, posts as p
     WHERE pl.pid = p.id    %s  %s      %s  
     HAVING distance < '%s'
     ORDER BY p.utc DESC, distance ASC LIMIT 0 , %s ",
     $loclat,
     $loclong,
     $loclat,   $status,    $type,  $start,
     $radius,   $limit);

У меня есть функция sprintf, которую можно использовать, пока я работаю над окончательной версией моего запроса. В настоящее время мне легче изменятьи т. д. Итак, я знаю, что наличие функции добавило бы время ... в первую очередь, сосредоточив внимание на самом запросе ... если есть что-то еще, СЛИШКОМ НЕПРАВИЛЬНО, я весь слух, но я верю, что часть HAVING является источником проблем.

Заранее спасибо!

Ответы [ 2 ]

2 голосов
/ 09 сентября 2011

Виновником является не само предложение HAVING, а все трансцендентные функции (sin, cos, acos), которые вы используете для вычисления расстояния.Они очень вычислительно дорогие.

Вы можете попытаться получить приблизительное расстояние, используя:

sqrt(x * x + y * y)

where x = 69.1 * (lat2 - lat1) 
and y = 53.0 * (lon2 - lon1) 

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

sqrt(x * x + y * y)

where x = 69.1 * (lat2 - lat1) 
and y = 69.1 * (lon2 - lon1) * cos(lat1/57.3) 

источник: http://www.meridianworlddata.com/Distance-Calculation.asp

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

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

Реальным решением является использование базы данных с поддержкой гео-пространственного типа данных (например, PostGIS).

...