SQl优化:在Where子句中使用相同的列两次使用OR,导致性能非常差

时间:2018-02-08 15:48:38

标签: sql oracle11g query-performance sqlperformance sql-tuning

我有联系人表格,其中包含Idsnameemaildelete和其他列。有大约500万的记录。

写下面的查询,然后在没有问题的情况下获得结果:

执行时间:< 2秒。

Select row_id 
from contact 
where row_id in (select row_id 
                 from Contact_details 
                 where email in ('abc@abc.com', 'xyz@xyz.com'))

但是当使用OR子句转换此查询时,至少默认选择0 row_id,它开始花费太长时间。

执行时间:> 120秒

Select row_id 
from contact 
where row_id=0 **OR** row_id in (select row_id 
                                 from Contact_details 
                                 where email in ('abc@abc.com', 'xyz@xyz.com'))

我已尝试使用union而不是使用OR,是的,这可以提高性能,但这是一个应用程序生成的查询,因此有一种方法可以在不使用union或union all的情况下改进此查询。

2 个答案:

答案 0 :(得分:1)

正如其他人所说,它在一定程度上取决于执行SELECT row_id FROM contact WHERE row_id = 0的时间。如果这很慢,那么OR就不会太过责备。

如果速度不慢,OR通常会在生成的计划中投入扳手(我很乐意看到所有这些查询的完整解释计划)。在这种情况下,你可以试试这个......

SELECT row_id 
  FROM contact 
 WHERE row_id IN (SELECT row_id 
                    FROM contact_details 
                   WHERE email in ('abc@abc.com', 'xyz@xyz.com')

                  UNION ALL

                  SELECT 0
                    FROM dual
                 )

(并向我们提供该查询的解释计划......)


<强> 编辑:

等等,你是 真的 只选择row_id,即使在外部查询中也是如此?如果是这样,那就这样做?

SELECT row_id 
  FROM contact 
 WHERE row_id IN (SELECT row_id 
                    FROM contact_details 
                   WHERE email in ('abc@abc.com', 'xyz@xyz.com')
                 )
UNION
SELECT 0
  FROM dual

答案 1 :(得分:0)

有时你可能会遇到OR的性能问题。在这种情况下,您可以使用UNION分割查询:

Select row_id 
from contact 
where row_id in (select row_id 
                       from Contact_details 
                       where email in ('abc@abc.com', 'xyz@xyz.com'))
UNION ALL
Select row_id 
from contact 
where row_id=0;