0

私たちのアプリでは、次の3つのテーブルを使用します。

  1. カテゴリ
  2. 都市(category_id)
  3. city_data(distance、city_id)
$q = "SELECT a.id as aid,a.distance as adistance, 
           b.id as bid,b.distance as bdistance 
        FROM city_data as a 
        JOIN city_data as b on a.id != b.id 
        JOIN cities AS a_cities ON a.city_id = a_cities.id
        JOIN cities AS b_cities ON b.city_id = b_cities.id      
        WHERE (a_cities.category_id='".$_GET["c"]."' AND b_cities.category_id='".$_GET["c"]."')
        AND abs(a.distance - b.distance) < 100 ORDER BY RAND() LIMIT 1";

テーブルcityscity_dataの行数は同じで、ほぼ5.000です。上記のクエリには約45秒かかりますが、これはひどいことです。さらに悪いことに、テーブルにはさらに5.000行が必要であり、合計で10.000行になります...

上記のクエリの実行時間を短縮する方法についてお聞きしたいのですが...45秒は受け入れられません...

この問題を解決するオプションはありますか?

編集:アドバイスありがとうございます 。ORDERBYRAND()の部分を削除しました。時間は非常に短く、約22秒ですが、これは通常の使用にはまだ長すぎます。

4

5 に答える 5

2

結合された列(cities.city_id、city_data.id、citys.category_id)にインデックスを作成したことを確認してください

于 2012-09-06T23:31:25.650 に答える
2

あなたのテーブルがどのように設計されているかはわかりませんが、city1 から city2 までの距離情報を 1 つの (おそらく別の) テーブルに保持し、最後の 2 つの結合を取り除き、別のクエリの結果のカテゴリ情報を取得する必要があります。

前に与えられたサンプルのように ( 400 都市間の距離を計算し、MySQL を最適化しますか? )

SELECT c1.name, c2.name, cd.dist 
FROM cities_dist cd
  INNER JOIN cities c1 ON cd.city1 = c1.id
  INNER JOIN cities c2 ON cd.city2 = c2.id
WHERE cd.city1 = your_id
   OR cd.city2 = your_id
ORDER BY cd.dist ASC

また、適切なインデックスとフィールド タイプの定義があることを確認してください。

于 2012-09-07T00:20:44.703 に答える
1

なぜこれを結合するのですか?

FROM city_data as a JOIN city_data as b on a.id != b.id 

city_dataテーブルのデータを、それらの間の一意の関係を一致させていない同じテーブルのデータと結合しています。これがクエリを非常に遅くしている原因だと思います。

于 2012-09-06T23:18:17.210 に答える
0

クエリを分割します。各サブクエリをビューに変換します。それらを個別に実行します。これにより、パフォーマンスを向上させることができます。通常、非常に複雑な 1 つの長いクエリを実行すると、単純化されたクエリを実行するよりも遅くなります。また、可能であれば、各サブクエリの結果を制限します。次に、ユニオンを使用して結果を結合できます。それが私の最初のアプローチです。

于 2012-09-06T23:48:23.737 に答える
0

このすべてのデータを PHP に戻し、そこでループ/距離計算を行うことは理にかなっているかもしれません。これは、DB よりもコードの方が速いかもしれません。

于 2012-09-07T00:16:03.440 に答える