1

場所で並べ替えられた結果を見つけるために使用するクエリがあります。結果は VAT も考慮する必要があるため、これもクエリに含まれます。残念ながら、キャッシュされていない場合、クエリの実行に 4 秒以上かかることがあります。明らかに明らかな問題を見つけたり、改善するために私にできることを提案したりできますか?

クエリで何が起こっているかを明確にするために:

  • 距離は、緯度/経度を使用したユークリッド距離で計算されます
  • incvat フィールドは、付加価値税が含まれている場合の価格を表示するために使用されます
  • WHEN / THEN ステートメントは、最下部に 0 の価格を配置するために使用されます。

クエリ:

SELECT * , ROUND( SQRT( POW( ( 69.1 * ( company_branch_lat - 52.4862 ) ) , 2 ) + POW( ( 53 * ( company_branch_lng - - 1.8905 ) ) , 2 ) ) , 1 ) AS distance, 
    hire_car_day + ( hire_car_day * 0.2 * ! hire_car_incvat ) AS hire_car_day_incvat, 
    hire_car_addday + ( hire_car_addday * 0.2 * ! hire_car_incvat ) AS hire_car_addday_incvat, 
    hire_car_week + ( hire_car_week * 0.2 * ! hire_car_incvat ) AS hire_car_week_incvat, 
    hire_car_weekend + ( hire_car_weekend * 0.2 * ! hire_car_incvat ) AS hire_car_weekend_incvat
FROM hire_car
LEFT JOIN company_branch ON company_branch_id = hire_car_branchid
LEFT JOIN hire_cartypelink ON hire_cartypelink_carhireid = hire_car_id
LEFT JOIN users ON company_branch_userid = user_id
WHERE 1 
GROUP BY hire_car_id
HAVING distance <=30
ORDER BY CASE hire_car_day_incvat
WHEN 0 
THEN 40000 
ELSE hire_car_day_incvat
END , distance ASC 
LIMIT 0 , 30
4

2 に答える 2

2

mysql 空間拡張機能を使用して、緯度と経度をポイント データ型として保存し、それを空間インデックスにすることができます。こうすることで、曲線に沿って座標を並べ替え、次元を減らして空間情報を保持できます。空間インデックスをバウンディング ボックスとして使用してクエリをフィルター処理し、harvesine 式を使用して最適な結果を選択できます。境界ボックスは、大円の半径よりも大きくする必要があります。Mysql はいくつかの空間インデックスを持つ rtree を使用し、私の例は az 曲線またはヒルベルト曲線に関するものでした:索引付け。次に、地理座標をポイント列に直接挿入できます: http://dev.mysql.com/doc/refman/5.0/en/creating-spatial-values.html. または、ジオメトリ データ型を使用できます: http://markmaunder.com/2009/10/10/mysql-gis-extensions-quick-start/。次に、MBRcontains 関数を次のように使用できます: http://dev.mysql.com/doc/refman/4.1/en/relations-on-geometry-mbr.htmlまたはその他の関数: http://dev.mysql.com /doc/refman/5.5/en/functions-for-testing-spatial-relations-between-geometric-objects.html . したがって、境界ボックスが必要です。ここではいくつかの例を示します。

ポイント データ型を使用した簡単な例を次に示します。

    CREATE SPATIAL INDEX sx_place_location ON place (location)

    SELECT  * FROM    mytable
    WHERE   MBRContains
           (
           LineString
                   (
                   Point($x - $radius, $y - $radius),
                   Point($x + $radius, $y + $radius)
                   )
           location
           )
    AND Distance(Point($x, $y), location) <= $radius

バウンディングボックス関数で半径変数を使用しているため、機能するかどうかはわかりません。MBRwithin は引数を必要としないため、少し単純なように思えます: Mysql: Optimizing finding super node in nested set tree

于 2012-11-27T23:25:23.983 に答える
0

GROUP BY ステートメントを HAVING と共に使用していますが、クエリのどこにも集計関数はありません。このようにクエリを書き直して、違いがあるかどうかを確認することをお勧めします

SELECT * , ROUND( SQRT( POW( ( 69.1 * ( company_branch_lat - 52.4862 ) ) , 2 ) + POW( ( 53 * ( company_branch_lng - - 1.8905 ) ) , 2 ) ) , 1 ) AS distance, 
hire_car_day + ( hire_car_day * 0.2 * ! hire_car_incvat ) AS hire_car_day_incvat, 
hire_car_addday + ( hire_car_addday * 0.2 * ! hire_car_incvat ) AS hire_car_addday_incvat, 
hire_car_week + ( hire_car_week * 0.2 * ! hire_car_incvat ) AS hire_car_week_incvat, 
hire_car_weekend + ( hire_car_weekend * 0.2 * ! hire_car_incvat ) AS hire_car_weekend_incvat
FROM hire_car
LEFT JOIN company_branch ON company_branch_id = hire_car_branchid
LEFT JOIN hire_cartypelink ON hire_cartypelink_carhireid = hire_car_id
LEFT JOIN users ON company_branch_userid = user_id
WHERE ROUND( SQRT( POW( ( 69.1 * ( company_branch_lat - 52.4862 ) ) , 2 ) + POW( ( 53 * ( company_branch_lng - - 1.8905 ) ) , 2 ) ) , 1 ) <= 30
ORDER BY CASE hire_car_day_incvat
WHEN 0 
THEN 40000 
ELSE hire_car_day_incvat
END , distance ASC 
LIMIT 0 , 30
于 2012-11-27T23:07:09.623 に答える