> ,ROUND( 6366.19773095 * ACOS( SIN(".$rad_lat1.") *SIN(RADIANS(ort1.geo_breite)) +COS(".$rad_lat1.") *COS(RADIANS(ort1.geo_breite)) *COS(RADIANS(ort1.geo_laenge) -".$rad_lon1." ))) distanz_km";
Problem:
- Das kann nicht indexiert werden.
Lösung:
- Ermittle erst einmal ein Viereck, dann geht die Abfrage mit größer und kleiner (Länge und Breite). Da kann der Index benutzt werden.
- Schließe dann die Werte, die außerhalb des Kreises liegen innerhalb von php aus.
$b = floatval($_REQUEST['B']);
$l = floatval($_REQUEST['L']);
$umkreis = round(abs($_REQUEST['umkreis']));
$startTime = microtime(true);
$umkreis_l = $umkreis/71.12;
$umkreis_b = $umkreis/87.27;
$b_max = $b + $umkreis_b;
$b_min = $b - $umkreis_b;
$l_max = $l + $umkreis_l;
$l_min = $l - $umkreis_l;
$counter=0;
sql = "SELECT nr,ort,breite,laenge FROM geo WHERE laenge > \"$l_min \" AND laenge < \"$l_max \" AND breite > \"$b_min \" AND breite < \"$b_max \" order by ort";
include("open.inc.php");
$result = mysqli_query($conn, $sql);
echo mysqli_error($conn)."<br>";
while ($row = mysqli_fetch_assoc($result)) {
$b_diff = 87.27 * abs($b-$row['breite']);
$l_diff = 71.11 * abs($l-$row['laenge']);
$entfernung = round(sqrt( $l_diff * $l_diff + $b_diff * $b_diff));
if ($entfernung <= $umkreis) {
echo "<td><a href=\"ortsinfo.php?nr=".$row['nr']."\">".$row['ort']."</a></td>";
echo "<td>".$row['breite']."</td>";
echo "<td>".$row['laenge']."</td>";
echo "<td>".$entfernung." km</td>";
echo "</tr>\n";
$counter++;
}
}
Das habe ich vor über 10 Jahren mal programmiert (heute würde ich manches besser machen) - es geht aber auch heute richtig schnell: