为什么SQL成本会随着简单的"or"而爆炸?



我有以下语句在我的数据中找到明确的名字(~100万个条目):

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

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
将其

调整到最佳不是我的问题,因为它只是一个很少执行的查询,而且我知道 CONTACT 超过了任何索引,但我只是想知道这种高成本来自哪里。这两个查询在语义上似乎等同于我。

答案在查询的解释计划中。 它们在语义上可能是等效的,但查询的幕后执行计划却大不相同。

EXISTS 的操作方式与 JOIN 不同,本质上,OR 过滤器语句是将表连接在一起的语句。

第二个查询中不会发生 JOIN,因为您只从一个表中检索记录。

两个查询的结果可能在语义上是等效的,但执行在操作上并不等效。第二个示例从不使用 OR 运算符来组合谓词。第二个示例中的所有谓词都使用 AND 进行组合。

性能更好,因为如果与 AND 组合的第一个谓词的计算结果未为 true,则跳过第二个谓词(或任何其他谓词)(不计算)。如果使用 OR,则必须经常计算两个(或所有)谓词,从而减慢查询速度。(检查 OR 谓词,直到一个谓词的计算结果为 true。

我会考虑测试重写的查询,如下所示...根据"合格"什么被认为是匹配的标准从一个直接加入到另一个...... 然后,在 WHERE 子句中,如果它没有匹配,则将其丢弃

select 
      p1.Prename, 
      p1.Surname
   from 
      person p1 
         join person p2
            on p1.ID <> p2.ID
            and (  p1.Surname = p2.Surname
                or p1.SurName = p2.AltName )
            and p2.PreName like concat( concat( '%', p1.Prename ), '%' )
   where
          p1.PreName is not null
      and p1.SurName is not null
      and p1.Inv_date is null
      and p2.id is null

根据您的评论,但从您正在寻找的内容来看......不,不要做左外连接... 如果您正在寻找要清除的相似名称(无论如何处理),则只需通过自联接(因此正常联接)对那些确实具有匹配项的记录进行资格预审。 如果你有一个名字没有相似的名字,你可能想不管它......因此,它将自动被排除在结果集之外。

现在,WHERE 子句开始了... 左边有一个有效的人...右边有一个人..这些是重复项...所以你有匹配,现在通过抛出逻辑"p2.ID IS NULL"创建与不存在相同的结果,给出最终结果。

我将查询恢复为正常的"连接"。

相关内容

  • 没有找到相关文章

最新更新