str*_*cer 7 sql oracle performance sqlperformance
我有以下声明在我的数据中找到明确的名称(约1百万条目):
select Prename, Surname from person p1
where Prename is not null and Surname is not null
and not exists (
select * from person p2 where (p1.Surname = p2.Surname OR p1.Surname = p2.Altname)
and p2.Prename LIKE CONCAT(CONCAT('%', p1.Prename), '%') and p2.id <> p1.id
) and inv_date IS NULL
Run Code Online (Sandbox Code Playgroud)
Oracle显示1477315000的巨额成本,并且执行不会在5分钟后结束.简单地将OR分成一个自己存在的子条款将性能提升到0.5秒,成本增加到45000:
select Prename, Surname from person p1
where Prename is not null and Surname is not null
and not exists (
select * from person p2 where p1.Surname = p2.Surname and
p2.Prename LIKE CONCAT(CONCAT('%', p1.Prename), '%') and p2.id <> p1.id
) and not exists (
select * from person p2 where p1.Surname = p2.Altname and
p2.Prename LIKE CONCAT(CONCAT('%', p1.Prename), '%') and p2.id <> p1.id
) and inv_date IS NULL
Run Code Online (Sandbox Code Playgroud)
把问题调整到最好是不是我的问题,因为它只是一个很少执行的查询,我知道CONTACT超过了任何索引,但我只是想知道这个高成本来自哪里.两个查询在语义上都与我相当.
答案在EXPLAIN PLAN中供您查询.它们在语义上可能是等价的,但是查询的幕后执行计划却大不相同.
EXISTS的操作与JOIN的操作不同,实质上,您的OR过滤器语句将表连接在一起.
第二个查询中没有JOIN,因为您只从一个表中检索记录.