高效的ANDing多个ID的ORing

时间:2018-09-05 16:45:21

标签: sql

基本上我想做这样的事情...

select * from table where (id1 = :var1 AND id2 = :var2) OR 
                          (id1 = :var2 AND id2 = :var1)

也就是说,这些ID将是唯一的,但是顺序并不重要。 上面的伪函数可以工作,但是我知道使用OR效率不高。 有没有更有效的方法来完成同一件事?

2 个答案:

答案 0 :(得分:4)

是的,有一种更有效的方法:UNION

select * from table where id1 = :var1 AND id2 = :var2
UNION ALL
select * from table where id1 = :var2 AND id2 = :var1
  • 全部联盟将保留重复项
  • UNION 将删除重复项

编辑以澄清

首先,应为您的id1id2列建立索引。

接下来,您的原始查询不是必需的“低效” 。这完全取决于查询引擎对OR的反应。

在这种情况下,在大多数RDBMS上经常发生找不到索引的路径的情况,这将导致全表扫描。

因此,只要涉及ANDOR的查询太长而无法执行,就应分析说明计划,以查看其是否使用索引。

另一方面,UNION查询将返回完全相同的结果,并且几乎可以保证引擎将正确使用索引。因此,最好立即对UNION表单进行编码。


顺便说一句,Oracle优化器第一步非常简单,称为 Query Transformer ,它可能会尝试将查询更改为UNION表单,然后再将其发送给 Plan Generator 。但是,如果查询太复杂,它将无法成功。

答案 1 :(得分:0)

这完全取决于数据库。通常,您的版本或此等效版本(如果数据库支持)将使用索引:

select t.*
from table t
where (t.id1, t.id2) in ((:var1, :var2), (:var2, :var1));

这应该被视为在(id1, id2)上具有两个值的索引中的简单查找。

有时候,使用union all可以重新措辞:

select t.*
from table t
where t.id1 = :var1 and t.id2 = :var2
union all
select t.*
from table t
where t.id1 = :var2 and t.id2 = :var1;

但是,在查看执行计划之前,我不会这样做。