【发布时间】:2013-12-30 04:48:27
【问题描述】:
我有一个包含大约 500 个点的表格,我正在寻找公差范围内的重复项。这需要不到一秒钟的时间,并给了我 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 秒。在我的积分表扩展到成千上万之前,这没什么大不了的。
如果答案已经存在,我提前道歉。我确实看过,但作为新手,我会迷失阅读那些让我头疼的帖子。
ADDENDUM: ObjectID 是一个 bigint 和 table 的 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
【问题讨论】:
-
SurveyPoint表上有索引吗?专栏SurveyPoint.ObjectID呢? -
SurveyPoint.ObjectID 是 PK 并已编入索引。我在几何列上也有一个空间索引。
-
你要加入同一张桌子吗?
-
你关心PointA和PointB不一样但是距离是0吗?如果您检查 PointA.Geometry.STDistance(PointB.Geometry) > 0 会怎样?
-
是的 - 同一张桌子。我们的想法是在同一个表中找到足够接近的点以被视为单个点。
标签: sql sql-server geospatial spatial-query