基本上我想做这样的事情...
select * from table where (id1 = :var1 AND id2 = :var2) OR
(id1 = :var2 AND id2 = :var1)
也就是说,这些ID将是唯一的,但是顺序并不重要。 上面的伪函数可以工作,但是我知道使用OR效率不高。 有没有更有效的方法来完成同一件事?
答案 0 :(得分:4)
是的,有一种更有效的方法:UNION
select * from table where id1 = :var1 AND id2 = :var2
UNION ALL
select * from table where id1 = :var2 AND id2 = :var1
首先,应为您的id1
和id2
列建立索引。
接下来,您的原始查询不是必需的“低效” 。这完全取决于查询引擎对OR
的反应。
在这种情况下,在大多数RDBMS上经常发生找不到索引的路径的情况,这将导致全表扫描。
因此,只要涉及AND
和OR
的查询太长而无法执行,就应分析说明计划,以查看其是否使用索引。
另一方面,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;
但是,在查看执行计划之前,我不会这样做。