6

約 500 ポイントを含むテーブルがあり、許容範囲内の重複を探しています。これには 1 秒もかからず、500 行が表示されます。同じ点 (PointA = PointB) を与えるため、ほとんどの距離はゼロです。

DECLARE @TOL AS REAL
SET @TOL = 0.05

SELECT 
    PointA.ObjectId as ObjectIDa,
    PointA.Name as PTNameA,
    PointA.[Description] as PTdescA,
    PointB.ObjectId as ObjectIDb,
    PointB.Name as PTNameB,
    PointB.[Description] as PTdescB,
    ROUND(PointA.Geometry.STDistance(PointB.Geometry),3) DIST
FROM CadData.Survey.SurveyPoint PointA
  JOIN [CadData].Survey.SurveyPoint PointB
    ON PointA.Geometry.STDistance(PointB.Geometry) < @TOL
   -- AND
   -- PointA.ObjectId <> PointB.ObjectID
ORDER BY ObjectIDa

一番下のコメントアウト行を使用すると、14 行になりますが、実行時間は最大 14 秒になります。私のポイント テーブルが数万に拡大するまでは、それほど大したことではありません。

答えがすでに出ている場合は、事前にお詫び申し上げます。私は見ましたが、新しいので、頭をはるかに超えた投稿を読んで迷子になります。

補遺: ObjectID は bigint であり、テーブルの PK であるため、ステートメントを次のように変更できることに気付きました。

AND PointA.ObjectID > PointB.ObjectID

これで半分の時間がかかり、半分の結果 (7 秒で 7 行) が得られます。重複がなくなりました (ポイント 4 がポイント 8 に近く、続いてポイント 8 がポイント 4 に近いなど)。ただし、テーブルが非常に大きくなるため、パフォーマンスの問題は依然として懸念されます。そのため、パフォーマンスの問題はすべて問題になります。

補遺 2: 以下のように JOIN と AND (または提案されている WHERE) の順序を変更しても違いはありません。

DECLARE @TOL AS REAL
SET @TOL = 0.05

SELECT 
    PointA.ObjectId as ObjectIDa,
    PointA.Name as PTNameA,
    PointA.[Description] as PTdescA,
    PointB.ObjectId as ObjectIDb,
    PointB.Name as PTNameB,
    PointB.[Description] as PTdescB,
    ROUND(PointA.Geometry.STDistance(PointB.Geometry),3) DIST
FROM CadData.Survey.SurveyPoint PointA
  JOIN [CadData].Survey.SurveyPoint PointB
    ON PointA.ObjectId < PointB.ObjectID
    WHERE
    PointA.Geometry.STDistance(PointB.Geometry) < @TOL
ORDER BY ObjectIDa

@Tol の値を大きな値に変更して、多くの計算が必要になるにもかかわらず、パフォーマンスを変更せずに 100 行を超える値を返すことができるのは魅力的です。しかし、単純な A を追加する

4

4 に答える 4