【问题标题】:Joining two tables on decimal (longitude/latitude) columns is *slow*在十进制(经度/纬度)列上连接两个表是*慢*
【发布时间】:2025-12-18 06:40:01
【问题描述】:

我有两个表,每个表都有标签、纬度、经度字段。我想拉出纬度和经度匹配的两个标签。这将创建新表 Label1、Label2、Latitude、Longitude。

SELECT Label1, Label2, Round(Latitude2,5) AS Expr1, Round(Longitude2,5) AS Expr2,Round(Latitude1,5) AS Expr3, Round(Longitude1,5) AS Expr4 INTO Merge
FROM [Table1], [Table2]
WHERE (((Round(Latitude2,5))=Round(Latitude1,5)) AND ((Round(Longitude2,5))=Round(Longitude1,5)));

这似乎让我陷入了一个循环,我很确定我明白为什么,但不能完全弄清楚如何得到我想要的。

感谢您的帮助!

【问题讨论】:

  • 你的查询,虽然写得不优雅,但应该做你想做的事。因为列上有函数 (round()),所以查询不能利用索引(如果有的话)。所以这很难优化。
  • 它似乎冻结了,我已经让它走了几分钟。每个表大约有 50,000 条记录,并且并非所有记录都匹配。这会导致问题吗?我应该给它更多时间吗?
  • 这取决于您在这些表上是否有多个相同的经纬度匹配。你可以得到比你想要的更多的行。假设您有(请原谅我不是真正的纬度和经度)lat, long 1,1 在表 1 中显示了 3 个不同的标签。lat, long 1,1 在表 2 中显示了 4 个不同的标签。您的加入会给出您支持 12 条记录,每个组合中的每个记录都连接在一起。
  • 这是一种可能性,也许我想让它变得更简单。我可能不得不在空间上接近这个,抓住任何带有 lat,longs 的标签靠近另一个。 --Edit 在一个位置有 12 个标签不会给我带来问题,除了让我的桌子太大/太慢。

标签: sql ms-access ms-access-2010


【解决方案1】:

正如问题的其中一个 cmets 中所述,您在连接条件中使用 Round() 函数这一事实意味着数据库引擎无法在经度和纬度字段上使用任何索引(如果甚至存在这样的索引)。这很可能是您遇到的性能不佳的原因。

我有一个包含两个表的测试用例,每个表有 5,000 行。 [Table1]的结构是

ID - 自动编号,主键
经度1 - 双
Latitude1 - 双
标签1 - 文字

[Table2]的结构相同,只是字段名称为[Longitude2]、[Latitude2]和[Label2]。

当我运行您在问题中发布的查询时,需要 10 分钟才能完成。

为了加快速度,我在每个表中添加了两个字段:[intLon] 和 [intLat],它们都定义为 Long Integer 并被索引。他们是这样填充的:

UPDATE Table1 SET
    intLon = Round(Longitude1, 5) * 100000,
    intLat = Round(Latitude1, 5) * 100000

UPDATE Table2 SET
    intLon = Round(Longitude2, 5) * 100000,
    intLat = Round(Latitude2, 5) * 100000

完成后,我们可以通过使用获得与初始查询相同的结果

SELECT Label1, Label2, Round(Latitude2,5) AS Expr1, Round(Longitude2,5) AS Expr2,Round(Latitude1,5) AS Expr3, Round(Longitude1,5) AS Expr4 INTO Merge
FROM 
    [Table1] 
    INNER JOIN 
    [Table2] 
        ON Table1.intLon = Table2.intLon 
            AND Table1.intLat = Table2.intLat

但不是需要 10 分钟来执行,而是需要 0.8 来运行。

【讨论】:

    最近更新 更多