SQL WHERE子句中的IN vs OR

时间:2010-06-19 07:17:20

标签: sql database

在处理SQL IN - 子句中表现更好,ORWhere的大型数据库时?

执行方式有什么不同吗?

6 个答案:

答案 0 :(得分:150)

我假设您想知道以下内容之间的性能差异:

WHERE foo IN ('a', 'b', 'c')
WHERE foo = 'a' OR foo = 'b' OR foo = 'c'

根据manual for MySQL,如果值是常量IN,则对列表进行排序,然后使用二进制搜索。我想,OR将按照一个接一个的顺序对它们进行评估。所以IN在某些情况下会更快。

最好的方法是在数据库中使用您的特定数据对其进行分析,以确定哪个更快。

我在1000000行的MySQL上尝试了两种方法。当列被索引时,性能上没有可辨别的差异 - 两者几乎是即时的。当列未编入索引时,我得到了以下结果:

SELECT COUNT(*) FROM t_inner WHERE val IN (1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000);
1 row fetched in 0.0032 (1.2679 seconds)

SELECT COUNT(*) FROM t_inner WHERE val = 1000 OR val = 2000 OR val = 3000 OR val = 4000 OR val = 5000 OR val = 6000 OR val = 7000 OR val = 8000 OR val = 9000;
1 row fetched in 0.0026 (1.7385 seconds)

因此,在这种情况下,使用OR的方法慢了约30%。添加更多术语会使差异更大。结果可能因其他数据库和其他数据而异。

答案 1 :(得分:31)

最好的方法是查看执行计划。


我尝试使用 Oracle ,它完全一样。

CREATE TABLE performance_test AS ( SELECT * FROM dba_objects );

SELECT * FROM performance_test
WHERE object_name IN ('DBMS_STANDARD', 'DBMS_REGISTRY', 'DBMS_LOB' );

即使查询使用IN,执行计划也会说它使用OR

--------------------------------------------------------------------------------------    
| Id  | Operation         | Name             | Rows  | Bytes | Cost (%CPU)| Time     |    
--------------------------------------------------------------------------------------    
|   0 | SELECT STATEMENT  |                  |     8 |  1416 |   163   (2)| 00:00:02 |    
|*  1 |  TABLE ACCESS FULL| PERFORMANCE_TEST |     8 |  1416 |   163   (2)| 00:00:02 |    
--------------------------------------------------------------------------------------    

Predicate Information (identified by operation id):                                       
---------------------------------------------------                                       

   1 - filter("OBJECT_NAME"='DBMS_LOB' OR "OBJECT_NAME"='DBMS_REGISTRY' OR                
              "OBJECT_NAME"='DBMS_STANDARD')                                              

答案 2 :(得分:6)

我认为oracle非常聪明,可以将效率较低的(无论哪种)转换为另一种。所以我认为答案应该取决于每个人的可读性(我认为IN明显胜出)

答案 3 :(得分:6)

OR运算符需要比IN结构更复杂的评估过程,因为它允许许多条件,而不仅仅是像IN一样。

以下是与OR一起使用但与IN不兼容的内容: 更大。更大或更小,更少,更少或相等,LIKE和更多像oracle REGEXP_LIKE。 另外考虑条件可能并不总是比较相同的值。

对于查询优化器,它更容易管理IN运算符,因为它只是一个构造,它在多个条件下定义OR运算符,并且=运算符在相同的值上。如果你使用OR运算符,优化器可能不会认为你总是在相同的值上使用=运算符,如果它没有执行更深入和更复杂的细化,它可能会排除可能只有=运算符在所有相关条件下的相同值,随后排除优化的搜索方法,如已经提到的二进制搜索。

[编辑] 可能优化器可能没有实现优化的IN评估过程,但这并不排除一次可能发生(使用数据库版本升级)。因此,如果使用OR运算符,则不会在您的情况下使用优化精化。

答案 4 :(得分:1)

OR有意义(从可读性的角度来看),当要比较的值较少时。 IN非常有用。如果您有动态源,您希望与之比较值。

另一种方法是将JOIN与临时表一起使用 如果您有必要的索引,我认为性能不应该是一个问题。

答案 5 :(得分:1)

我在大量的OR(350)中进行了SQL查询。 Postgres做到 437.80ms

Use OR

现在使用IN:

Use IN

<强> 23.18ms