【发布时间】:2013-06-06 20:04:35
【问题描述】:
问题:我们想从我们的数据库中删除拼写错误的地址。但是我们有太多的事情要做。因此,我有一个函数 FN,如果两个地址看起来非常相似(表明可能拼写错误),它会返回 true。一个简单的检查是做类似...
select *
from
address adr1
join address adr2
on FN(adr1, adr2)
但是,这基本上是进行交叉连接并比较行。由于我们的表有多大(> 100 万行),这是不可能做到的。但是,我可以将其限制为仅查看彼此附近的地址。例如,同一城市内的地址。所以,我试着做这样的地址计数......
select count(1)
from
address adr1
join address adr2
on adr1.zip = adr2.zip
and adr1.city = adr2.city
--Don't want to compare to self
and adr1.ID <> adr2.ID
问题是这需要很长时间才能运行(我已经等了,但它还没有完成)。我怀疑 oracle 有更好的方法来处理大量行的这些类型的事情,但我只是不知道。
那么,如果有办法限制要连接的内容(例如只查看相同的邮政编码),那么一个人应该如何将一个超大的表连接到自己呢?
附:数万亿条记录算大数据还是应该去掉标签?
Edit1:Zip 和 City 已编入索引。
Edit2:Zip 和 City 都有大量 200,000+ 的空值。这可能会影响索引在连接中的使用方式。
解释计划:
SELECT STATEMENT ALL_ROWSCost: 35,301 Bytes: 42 Cardinality: 1
4 SORT AGGREGATE Bytes: 42 Cardinality: 1
3 HASH JOIN Cost: 35,301 Bytes: 2,195,769,492 Cardinality: 52,280,226
1 TABLE ACCESS FULL TABLE SCHEMA.ADDRESS Cost: 15,677 Bytes: 21,388,962 Cardinality: 1,018,522
2 TABLE ACCESS FULL TABLE SCHEMA.ADDRESS Cost: 15,677 Bytes: 21,388,962 Cardinality: 1,018,522
Edit3:我尝试过以不同的方式计算行数。
select
sum(cnt * (cnt - 1))
from
(
select
count(1) as CNT
from schema.address adr1
group by adr1.zip, adr1.city
)
这在不到 10 秒的时间内返回了约 450 亿个不同的配对。我不确定我的函数是否可以每秒处理超过 100k 行,而这正是在 12 小时内运行所需要的。
【问题讨论】:
-
你的
FN有多复杂? -
您的第二个查询看起来没问题。 Oracle 有办法处理连接大量数据,例如使用哈希连接。 100 万行甚至不是真正的大量数据。如果您发布说明计划,有人可能会帮助您调整查询。
-
@Gerrat 我会说非常讨厌,因为它正在执行各种字符串操作并涉及上下文切换。话虽这么说,这对于尝试优化连接是否重要?
-
我问的唯一原因是,如果它不是太复杂,那么可能有比首先使用函数和连接更好的方法。不过,这似乎是不可能的。
-
我只是要提一下(在您最近的编辑之前),即使您可以解决加入问题,我敢打赌您的功能将花费太长时间。您提到 100000/秒...如果它正在执行上下文切换,它可能只能进行 1000 次比较/秒。我认为您可能想尝试另一种方法 - 也许导出您的数据,将其按 soundex 之类的东西分组,然后从那里开始。