4

各ユニットの位置が座標によって定義されている 300'000 ユニットのセットを持つテーブルがあります(X,Y)。各ユニットから特定の距離内にあるユニットを知りたいのですが?

元。

UnitiID   X   Y
A         10  15
B         10  25
C         25  15


proc sql;
    create table work.Test2 as
    select distinct
    a.UnitID,
    a.X,
    a.Y,
    b.UnitID as CloseUnit label="CloseUnit",
    sqrt( (a.X-b.X)**2 + (a.Y-b.Y)**2 ) as distance
    from
    work.Test as a
    left join
    work.Test as b
    on
    0<sqrt( (a.X-b.X)**2 + (a.Y-b.Y)**2 ) <=15
    ;
quit;

結果:

UnitiID   X   Y   CloseUnit  Distance
A         10  15  B          10
A         10  15  C          15
B         10  25  A          10
C         25  15  A          15

300,000^2 の比較を行うため、テーブル全体で多くの CPU 時間を必要とします。このタスクを実行するにはどうすればよいでしょうか?

4

1 に答える 1

3

いくつかの最適化が思い浮かびます。まず、X 軸と Y 軸に沿った距離を確認できます。いずれかが 15 より大きい場合、ポイントは範囲内にありません。サブクエリは、最初に高速なチェックを行うようにデータベースに指示します。

select  *
from    (
        select  a.X as aX
        ,       b.X as bX
        ,       a.Y as aY
        ,       b.Y as bY
        from    Test a
        join    Test b
        on      abs(a.X - b.X) <= 15
                and abs(a.Y - b.Y) <= 15
        ) as SubQueryAlias
where   sqrt( (aX-bX)**2 + (aY-bY)**2 ) <= 15

2 番目の最適化は、sqrt計算を右に移動することです。

where   (aX-bX)**2 + (aY-bY)**2 <= 15**2

二乗は、ルート化よりも高速であり、特に定数に対して行う場合に顕著です。

さらに最適化するには、ジオハッシュに関するウィキペディアの記事を参照してください

于 2012-08-01T14:14:41.633 に答える