0

100 万を超える場所を含むテーブルがあります

  • ID
  • 住所
  • 経度
  • 緯度

ユーザーは住所を入力すると、Google マップで半径 5 km の最寄りの場所を取得できます。

私の選択クエリ:

$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 か所を超えると Google マップが表示されないことです。LIMIT 0,10 を使用したくありません。すべての結果を表示したいのです。

大きなテーブルから毎回 10% ずつ検索するようにクエリを分割するにはどうすればよいですか?

ページの読み込み後に実行時にマーカーを配置するようなものです。

4

3 に答える 3

1

明確にしていただきありがとうございます。これが私の編集された答えです。

問題は、データベースに再度クエリを実行することなく、クエリの結果をより小さな部分に分割する効率的な方法が必要であるように思われます。あなたが提供した例では、ロケーションベースのクエリは 10,000 の結果のリストを生成します。その結果は、データベースに戻らずに、それぞれ 1,000 の 10 のチャンクにさらに sub0divide します。これは、10,000 件の結果を返した元のクエリがそもそも遅いためであり、一度に 1,000 件の結果をクエリするのも同様に遅いためだと思います。

この問題にはいくつかの解決策が考えられますが、どれを選択するかは、アプリケーションでデータがどのように使用されるかによって異なります。このクエリはアプリケーションの 1 人のユーザーに固有のものですか、それとも数十、数百、または数千のユーザーが使用する別のバリ​​エーションですか?

アプリケーションのすべてのユーザーが同じクエリを使用している場合、cron ジョブを使用して、クエリ全体の結果を (準) 一時テーブルに選択します。このテーブルは、キャッシュされたデータを格納するためだけに存在します。一度に 1,000 の結果をページ表示するときは、キャッシュされたテーブルに対してクエリを実行します。すべての距離が事前に計算され、harsine 式を再度実行する必要がないため、これははるかに高速です。

同じクエリの多くのバリエーションがアプリケーションのすべてのユーザーによって使用されている場合、クエリの結果全体をシリアル化された配列としてユーザーのセッションに格納することもできます。次に、一度に 1,000 件の結果を処理する必要があるたびに、セッションに格納されている順序付けられた配列から読み取り、適切な結果を生成します。

アプリケーション全体でこのクエリの数千または数百万のバリエーションに直面している場合、高速化する最善の方法は、データの保存方法/場所、および/またはデータへのアクセス方法を再考することです。このオプションが短期的には実行できない可能性があることはわかっていますが、効率を劇的に変えるには、このような変更が必要になる場合があります。それが多少役立つことを願っています!

于 2013-09-12T14:50:56.083 に答える
0

私の失敗した試み#1:毎回大きなテーブルから1000レコードを選択しようとし、次にJSを使用して各レコードが半径5kmにある場合は計算し、そうである場合はマップに表示します..ソースコードはどうなりましたか多くのJSによって成長しました..

これは Google マップの 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;
于 2013-09-13T14:18:28.547 に答える