У меня две таблицы: таблица карт, содержащая около 3000 пар лат /lng, представляющих реальные "маркерные" местоположения; и таблица "Здания", в которой есть несколько сотен пар лат /lng, также представляющих реальные местоположения зданий. То, что я пытаюсь сделать, - это получить все маркеры, которые видны из всех зданий, при условии, что здания имеют "диапазон видимости", определенный отдельно. У меня есть полностью работающий PHP-скрипт, который работает успешно:
<?php
// query the Buildings table to get the building data we need
$sql = "SELECT type, lat, lng FROM Buildings;";
$result = mysqli_query($conn, $sql);
while ($row = mysqli_fetch_assoc($result)) {
$allBuildings[] = $row;
}
$result -> close();
// count how many buildings there are to save time in the loop
$buildingsNumber = count($allBuildings);
// this is the key query, which runs a SELECT query for every building so that only the markers visible by the buildings are shown
for ($i = 0; $i < $buildingsNumber; $i++) {
// get the building lat/lng
$lat = $allBuildings[$i]["lat"];
$lng = $allBuildings[$i]["lng"];
// get the building vision range in metres
$distance = $buildings[$allBuildings[$i]["type"]]["vision_range"];
// this is the core query. it is a radius search using lat/lngs with the centre being the building location and the radius being its vision_range
$sql = "SELECT Map.lat, Map.lng,
(6378137 * acos(cos(radians($lat)) * cos(radians(lat)) * cos(radians(lng) - radians($lng)) + sin(radians($lat)) * sin(radians(lat))))
AS distance FROM Map
HAVING distance < $distance;";
while ($row = mysqli_fetch_assoc($result)) {
$markersArray[] = $row;
}
}
?>
Проблема заключается в том, что для этого количества отдельных запросов результат возвращается примерно через 20-30 секунд. Это имеет смысл, так как кажется, что поездка с моего сервера PHP на мой сервер MySQL занимает около 30 мс. Мне нужен запрос, который возвращает результаты почти мгновенно, поэтому в идеале я хочу избежать этих нескольких раундов и отправить один запрос, который возвращает один набор результатов.
Я ранее пытался использовать mysqli_multi_query в разных запросах, но я никогда не получал его, чтобы он работал успешно. Я также думал об объединении запросов, но я не уверен, что это сработает. Кто-нибудь успешно смог сделать что-то подобное? Или может кто-нибудь предложить способ перезаписать мой скрипт, который потребует только одного запроса SELECT?
Большое спасибо, Джордж
Спасибо emma за это предложение. Вот приведенный выше сценарий, переписанный для перемещения запросов SELECT за цикл for и использования множественного запроса для результата:
<?php
// query the Buildings table to get the building data we need
$sql = "SELECT type, lat, lng FROM Buildings;";
$result = mysqli_query($conn, $sql);
while ($row = mysqli_fetch_assoc($result)) {
$allBuildings[] = $row;
}
$result -> close();
// count how many buildings there are to save time in the loop
$buildingsNumber = count($allBuildings);
// this is the key query, which runs a SELECT query for every building so that only the markers visible by the buildings are shown
for ($i = 0; $i < $buildingsNumber; $i++) {
// get the building lat/lng
$lat = $allBuildings[$i]["lat"];
$lng = $allBuildings[$i]["lng"];
// get the building vision range in metres
$distance = $buildings[$allBuildings[$i]["type"]]["vision_range"];
// this is the core query. it is a radius search using lat/lngs with the centre being the building location and the radius being its vision_range
$sql .= "SELECT Map.lat, Map.lng,
(6378137 * acos(cos(radians($lat)) * cos(radians(lat)) * cos(radians(lng) - radians($lng)) + sin(radians($lat)) * sin(radians(lat))))
AS distance FROM Map
HAVING distance < $distance;";
}
// note two important things: multi query doesn't work without the MYSQLI_USE_RESULT flag, and we don't close a multi query result otherwise we get server errors
$result = mysqli_multi_query($conn, $sql, MYSQLI_USE_RESULT);
while ($row = mysqli_fetch_assoc($result)) {
$markersArray[] = $row;
}
?>
Обратите внимание на важность моего последнего комментария относительно множественного запроса, поскольку это вызвало у меня много горя.
for
- а также ты думал об использовании PDO? : D Вы можете устранить это пока цикл, а также: D