0

我有一张包含数百万个地点的桌子

  • ID
  • 地址
  • 经度
  • 纬度

用户可以输入一个地址,他可以在谷歌地图中以 5 公里半径获得最近的位置。

我的选择查询:

$result = mysql_query("SELECT *, ( 6371 * acos( cos( radians(".$lat1.") ) * cos( radians( lat ) ) * cos( radians( lng ) - radians(".$lng1.") ) + sin( radians(".$lat1.") ) * sin( radians( lat ) ) ) ) AS distance FROM star HAVING distance < ".$rad." ORDER BY distance");

表格上的结果,在 javascript <> 内

 while ($row = mysql_fetch_array($result)) {
   echo "    
   var marker".$row{'id'}." = new google.maps.Marker({
    position: new google.maps.LatLng(".$row{'lat'}." , ".$row{'lng'}."),
    map: map
    });
    var infowindow".$row{'id'}." = new google.maps.InfoWindow({
    content: 'City : ".$row{'city'}.", Address : ".$row{'address'}." , Lat : ".$row{'lat'}." , Lng : ".$row{'lng'}."'
    });
    google.maps.event.addListener(marker".$row{'id'}.", 'click', function() {
    infowindow".$row{'id'}.".open(map, marker".$row{'id'}.");
    });
    ";
}

我的问题是当它超过 10 个位置时,它不显示谷歌地图。我不想使用 LIMIT 0,10,我想显示所有结果。

如何将查询拆分为每次从大表中搜索 10%?

在页面加载后将标记置于运行时。

4

3 回答 3

1

感谢您的澄清。这是我编辑的答案。

问题似乎是您想要一种有效的方法将查询结果分解成更小的部分,而不必重新查询数据库。在您提供的示例中,基于位置的查询将生成一个包含 10,000 个结果的列表,您希望将其结果进一步细分为 10 个块,每个块 1,000 个,而无需返回数据库。我认为这是因为返回 10,000 个结果的原始查询开始时很慢,并且一次查询 1,000 个结果也同样慢。

这个问题有几种潜在的解决方案,您选择哪一种取决于应用程序中数据的使用方式。这个查询是应用程序的单个用户独有的,还是被数十、数百或数千名用户使用的不同变体?

如果您的应用程序的所有用户都使用相同的查询,那么我将使用 cron 作业将整个查询的结果选择到(准)临时表中。该表仅用于存储缓存数据。当您一次翻阅 1,000 个结果时,您将查询缓存的表。这会快得多,因为所有的距离都是预先计算好的,您不必再次运行半正弦公式。

如果您的应用程序的所有用户都在使用同一查询的许多变体,您还可以将查询的整个结果作为序列化数组存储在用户会话中。然后,每次您需要检查结果时,一次 1,000 个,您将从存储在会话中的有序数组中读取,并生成适当的结果。

如果您在整个应用程序中面临数千或数百万种此查询的变体,那么使其更快的最佳方法是重新考虑数据的存储方式/存储位置和/或访问方式。我知道这个选项在短期内可能不可行,但有时需要这样的改变才能产生效率的巨大变化。我希望这有所帮助!

于 2013-09-12T14:50:56.083 回答
0

关于在页面加载后将标记放在运行时的事情

一种简单的方法是通过 http 端点公开搜索功能并使用 AJAX 进行查询,而不是使用结果重新加载页面

# search.php

$lat = $_POST['lat'];
$lng = $_POST['lng'];
$locations = search_for_close_locations($lat, $lng);
echo json_encode($locations);

# your_page.js
// attache event handler to the lat/lng input
$('#lat_lng_input_form').submit(function() {
  $.getJSON('/search.php', function(response) {
     // clear all previous markers 
     // place new markers
  });
});
于 2013-09-12T14:40:09.617 回答
0

我的失败尝试#1:尝试每次从大表中选择 1000 条记录,然后使用 JS 计算每条记录是否在 5 公里半径内,如果是,则在地图上显示.. 发生了什么是源代码由很多 JS 成长..

这是在谷歌地图初始化()函数中:

$q = "select MAX(id) from table";
$res1 = mysql_query($q);
$data1 = mysql_fetch_array($res1);
$max =  $data1[0];
$start = 1;
$end = 1000;
 while($end < $max) {
    $result = mysql_query("SELECT * FROM table WHERE id > ".$start." AND id < ".$end);
    while ($row = mysql_fetch_array($result)) {
?>
        if(getDistanceFromLatLonInKm(<?php echo $lat1." , ".$lng1." , ".$row{'lat'}." , ".$row{'lng'} ?>) < 5) {
            addMarker(<?php echo $row{'lat'}.",".$row{'lng'}; ?>);
        }
<?php
    }
    $start = $start + 1000;
    $end = $end + 1000;
于 2013-09-13T14:18:28.547 回答