SQL WHERE 절에서 IN 대 OR


150

큰 데이터베이스를 다룰 때 더 나은 성능을 보 입니까 , IN아니면 ORSQL 절에서 Where?

그들이 실행되는 방식에 차이가 있습니까?


내 첫 번째 추측은 SQL 엔진이 IN을 뒤에서 OR로 변환하지 않는 한 OR이 더 잘 수행된다는 것입니다. 이 두 가지 쿼리 계획을 보셨습니까?
Raj

답변:


170

다음과 같은 성능 차이를 알고 싶다고 가정합니다.

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

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 % 느립니다. 용어를 더 추가하면 차이가 커집니다. 결과는 다른 데이터베이스 및 다른 데이터에 따라 달라질 수 있습니다.


20
옵티마이 저가 소금의 가치가 있다면 동일하게 수행해야합니다.
Janick Bernet

27
@inflagranti : 불행히도 최적화 프로그램이 없습니다. 최적화 프로그램은 매우 복잡한 프로그램이며 각 구현에는 고유 한 장단점이 있습니다. 이것이 바로 특정 구현에 대해 프로파일 링해야한다고 말하는 이유입니다. IN메소드 의 추가 구조로 인해 관련 OR절 전체를 최적화하는 것이 더 쉽다고 생각 합니다. OR방법이 더 빠른 엔진이 있다면 놀랄 것입니다. 그러나 OR이 느릴 때가 있습니다.
Mark Byers

2
@MarkByers는 옵티마이 저는 항상 여러 대체 할 수 없습니다 OR로들 IN?
tymtam

36

확인하는 가장 좋은 방법은 실행 계획을 보는 것입니다.


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')                                              

1
테스트중인 값이 3 개를 초과하면 Oracle에서 어떻게됩니까? Oracle이 MySQL과 동일한 이진 검색 최적화를 수행 할 수 없는지 또는 두 경우 모두 수행합니까?
Mark Byers

2
@ Mark Byers : 10 개의 값으로 동일한 쿼리를 시도했지만 여전히 동일한 결과를 얻었습니다. 옵티마이 저는 알파벳 순서로 내 값을 사용했습니다. 오라클이 그 필터의 내부 최적화를했다고해도 놀라지 않을 것입니다.
Peter Lang

5
또한 Oracle에는 INLIST ITERATOR사용할 수있는 인덱스가있는 경우 선택 하는 작업이 있습니다. 그럼에도 불구하고, 나는 그것을 밖으로 시도, 두 때 INOR동일한 실행 계획을 끝낸다.
Cheran Shunmugavel

7

OR 연산자는 IN과 같을뿐만 아니라 많은 조건을 허용하므로 IN 구문보다 훨씬 복잡한 평가 프로세스가 필요합니다.

다음은 OR과 함께 사용할 수 있지만 IN과 호환되지 않는 것과 비슷합니다. 크거나 같음, 작음, 작음 또는 같음, LIKE 및 오라클 REGEXP_LIKE와 비슷합니다. 또한 조건이 항상 동일한 값을 비교하지는 않을 수도 있습니다.

쿼리 최적화 프로그램의 경우 IN 연산자를 관리하기가 더 쉽습니다. 동일한 값에 = 연산자를 사용하여 여러 조건에서 OR 연산자를 정의하는 구문 만 있기 때문입니다. OR 연산자를 사용하는 경우 옵티마이 저는 항상 같은 값으로 = 연산자를 사용한다고 생각하지 않을 수 있으며 더 깊고 훨씬 더 복잡한 정교화를 수행하지 않으면 아마도 = 이미 언급 된 이진 검색과 같은 최적화 된 검색 방법을 배제하여 관련된 모든 조건에서 동일한 값에 대한 연산자.

[편집] 아마 옵티마이 저는 최적화 된 IN 평가 프로세스를 구현하지 않을 수도 있지만 (데이터베이스 버전 업그레이드시) 한 번만 발생할 수 있다는 것을 배제하지는 않습니다. 따라서 OR 연산자를 사용하면 최적화 된 정교화가 사용되지 않습니다.


6

오라클은 효율성이 떨어지는 하나 (둘 중 어느 쪽이든)를 다른 것으로 변환 할 수있을만큼 똑똑하다고 생각합니다. 그래서 나는 대답이 오히려 각각의 가독성에 달려 있어야한다고 생각합니다 (제 생각에 IN분명히 승리합니다)


2

OR비교할 값이 적을 때 (가독성 관점에서) 의미가 있습니다. IN유용한 esp. 값을 비교하려는 동적 소스가있는 경우

다른 대안은 JOIN임시 테이블과 함께 사용하는 것 입니다.
필요한 색인이 있다면 성능이 문제가되지 않는다고 생각합니다.


-2

많은 OR (350)에서 SQL 쿼리를 수행했습니다. Postgres는 437.80ms를 수행합니다 .

OR 사용

이제 IN을 사용하십시오.

IN 사용

23.18ms


4
IN 절에 대해 하위 쿼리를 사용했기 때문에 이는 전혀 다릅니다.
gliljas
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.