2010-10-18 25 views
1

我正面临一个问题。我有一个查询不使用OR子句的查询性能

Select * from tabA 
where (a) in (a,b,c) 
OR b in (a,b,c) 

我要面对的性能问题,由于这个查询,因为我需要删除或条件,所以我试着用下面的查询:

Select * from tabA 
where (a,b) in (a,b,c) 

但此查询,似乎不工作,请帮助。我不想使用'或'条件。

+0

做些什么指标你有tabA吗?您可能需要列a和b上的复合索引。并且对查询做一个解释计划,这将有助于确认性能问题的可能性。 – 2010-10-18 13:21:41

回答

4

如果您逻辑上需要OR条件,那么这就是您所需要的。使用OR没有任何问题。如果两列索引则查询可能采取不超过独立运行这两个查询:

select * from tabA 
where a in (a,b,c); 

select * from tabA 
where b in (a,b,c); 

优化可能做到这一点,连接结果是这样的:

Execution Plan 
---------------------------------------------------------- 
    0  SELECT STATEMENT Optimizer=CHOOSE (Cost=4 Card=2 Bytes=256) 
    1 0 CONCATENATION 
    2 1  TABLE ACCESS (BY INDEX ROWID) OF 'TABA' (Cost=2 Card=1 Bytes=128) 
    3 2  INDEX (RANGE SCAN) OF 'TABA_A_IDX' (NON-UNIQUE) (Cost=1 Card=1) 
    4 1  TABLE ACCESS (BY INDEX ROWID) OF 'TABA' (Cost=2 Card=1 Bytes=128) 
    5 4  INDEX (UNIQUE SCAN) OF 'TABA_B_IDX' (NON-UNIQUE) (Cost=1 Card=1) 
3

如果逻辑仍然是相同的 - 你可以尝试UNION

Select * from tabA 
where (a) in (a,b,c) 
union 
Select * from tabA 
where b in (a,b,c) 

另外,检查你的索引和解释计划的结果 - 索引可以解决原来或问题。

+0

详细说明,UNION ALL可能会产生重复行,其中column_a匹配的value_a和column_b匹配的value_c将由两个SELECT返回。 UNION会做一个DISTINCT,所以删除重复。只要select包含主键列,DISTINCT仍然会为数据库中的每个匹配行赋予一行。 – 2010-10-18 21:42:32

2

你用错误的语法,如果你想配对比较值,你应该使用水木清华这样的:

select * from tabA 
where (a,b) in ((a,b), (a,c), (b,c) etc. 

反正in条件转化为多个查询执行期间or条件。

只要您显示表结构和执行计划,人们将能够更有效地帮助您。