问题:我们想从我们的数据库中删除拼写错误的地址。但是我们有太多的事情要做。因此,我有一个函数 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 有更好的方法来处理大量行的这些类型的事情,但我只是不知道。
那么,如果有办法限制正在加入的内容(例如只在同一个邮政编码中查找),那么一个人应该如何将一个极大的表加入到自己身上呢?
PS 数以万亿计的记录算作大数据还是应该删除标签?
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 小时内运行所需要的。