将大查询拆分为谷歌地图

时间:2013-09-12 14:29:14

标签: javascript php mysql google-maps-api-3

我有一张超过百万个席位的桌子

  • 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&lt;&gt;内

 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%?

在页面加载后将标记放在运行时的东西。

3 个答案:

答案 0 :(得分:1)

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

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

此问题有几种可能的解决方案,您选择哪种解决方案取决于数据在应用程序中的使用方式。此查询对您的应用程序的单个用户是唯一的,还是由数十,数百或数千个用户使用的不同变体?

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

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

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

答案 1 :(得分: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
  });
});

答案 2 :(得分:0)

我的失败尝试#1: 试图从大表中每次选择1000条记录,然后使用JS计算每条记录,如果它在5公里范围内,如果是,则在地图上显示它......以及JS代码增长的源代码是什么。

这是在google map initialize()函数中:

$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;