1

同じデータのサブセットに対して 4 つのかなり大きな MySQL クエリを実行する必要があるスクリプトがあります。それらを 1 つのクエリに結合する方法はありますか?

クエリは次のようになります。

Select sum(value) From 
    ( Select lat, lng, value From `pop_geo_199` Where (
         (lat Between 38.1768916977 And 39.6131083023) And (lng Between -77.9596650363 And -76.1143349637)) 
        ) As FirstCut 
Where (acos(0.627895140732*sin(radians(lat)) + 0.778297945677*cos(radians(lat))*cos(radians(lng)-(-1.34454929586))) * 6371 < 79.85)

お分かりのように、これは緯度と経度の地理的なクエリです。クエリが行うことは、最初に合計テーブル ( FirstCut) の単純な正方形のサブセットを作成し、次に三角関数を実行して円形の領域を取得することです。

私が知る限り、遅いクエリの部分は です。クエリFirstCutが描画しているテーブルには約 280 万行あるためです。FirstCutですが、この例では約 27,922 行しかないため、比較すると三角部分は非常に高速です。

問題は、これらのいくつかを実行する必要があることです。FirstCutただし、同じ領域を中心とする異なる半径であるため、すべて同じ を使用できます。4 つではなく 1 つのクエリでこれを実行できるようにしたいと考えています。

2 番目のクエリは次のようになります。

Select sum(value) From 
    ( Select lat, lng, value From `pop_geo_199` Where (
         (lat Between 38.1768916977 And 39.6131083023) And (lng Between -77.9596650363 And -76.1143349637)) 
        ) As FirstCut 
Where (acos(0.627895140732*sin(radians(lat)) + 0.778297945677*cos(radians(lat))*cos(radians(lng)-(-1.34454929586))) * 6371 < 48.57) 

ご覧のとおり、最後の WHERE 句がわずかに異なることを除いて、他のものとまったく同じです。条件は半径が小さいだけです (79.85 ではなく 48.57)。

これら 2 つのクエリを効率的な方法で 1 つのクエリに結合するにはどうすればよいですか?

CASE 句を使用してみました -- これが最善の方法ですか?

Select 

sum(case when (acos(0.627895140732*sin(radians(lat)) + 0.778297945677*cos(radians(lat))*cos(radians(lng)-(-1.34454929586))) * 6371 < 79.85) then value else 0 end),

sum(case when (acos(0.627895140732*sin(radians(lat)) + 0.778297945677*cos(radians(lat))*cos(radians(lng)-(-1.34454929586))) * 6371 < 48.57) then value else 0 end)

From ( Select lat, lng, value From `pop_geo_199` Where ((lat Between 38.1768916977 And 39.6131083023) And (lng Between -77.9596650363 And -76.1143349637)) ) As FirstCut;
4

1 に答える 1

1

CASEこれにはステートメントを使用できます。計算をサブクエリに移動することもできます。

Select 
     sum(case 
           when rad < 79.85
           then value 
           else 0 end)  1stQuerySum,
     sum(case 
           when rad < 48.57 
           then value 
           else 0 end)  2ndQuerySum
From  ( 
    Select lat, lng, value, 
           acos(0.627895140732*sin(radians(lat)) + 0.778297945677*cos(radians(lat))*cos(radians(lng)-(-1.34454929586))) * 6371 rad
    From `pop_geo_199` 
    Where (
         (lat Between 38.1768916977 And 39.6131083023) And 
         (lng Between -77.9596650363 And -76.1143349637)
    ) 
) As FirstCut 
于 2013-07-21T16:47:39.530 に答える