【问题标题】:Split big query to google maps将大查询拆分到谷歌地图
【发布时间】:2013-09-12 14:29:13
【问题描述】:

我有一张包含数百万个位置的表格

  • 身份证
  • 地址
  • 经度
  • 纬度

用户可以输入一个地址,他可以在谷歌地图中以 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%?

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

【问题讨论】:

  • 您遇到错误了吗?当您尝试检索超过 10 个位置时,您的 JS 控制台会显示什么?
  • 没有错误,JS代码在页面源代码中,但是没有显示地图

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


【解决方案1】:

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

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

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

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

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

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

【讨论】:

  • 正如您在我的问题示例中看到的,我的 select SQL 语句得到了结果,它检查大表中的每个 id 以查看位置是否在给定地址的 5 公里半径内,我想使其更具可扩展性,我如何编辑我的代码以每次搜索 10% 的表,以及当页面打开时显示 10% 的结果,然后在运行时搜索 10% 时,类似于:Table with id 从 1 到 10,000,页面加载 > 在谷歌地图上显示 id 1 到 1000 的最近位置,之后在运行时将结果从 id:1001 到 id:2000 添加到地图中
  • 嗨,吉姆,我已经编辑了我的原始答案。我希望它更有帮助。
  • 首先感谢 Jay Sheth!我在表中有一个随机位置,所以无法更改,我只是认为每次查询 1,000 并使用 jQuery 检查它会比使用 MySql 检查所有 10,000 更快,仍然不知道如何在该页面加载后执行此操作.. 现在阅读并尝试遵循这个 tut:openenergymonitor.org/emon/node/107
【解决方案2】:

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

执行此操作的一种简单方法是通过 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
  });
});

【讨论】:

  • 您能否展示或链接到这种简单方法的示例?
【解决方案3】:

我失败的尝试#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;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-11
    • 2014-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多