2010-06-19 3 views
119

더 나은 성능을 나타내는 큰 데이터베이스를 처리 할 때 Where 절에 IN 또는 OR? 절?IN OR SQL where 절에서

실행 방법에 차이가 있습니까?

+0

내 첫번째 추측 그렇게이거나 SQL 엔진으로 또는 장면 뒤에 변환하지 않는 한, 더 나은 수행하는 것 . 이 두 쿼리 계획을 보았습니까? – Raj

+0

[MYSQL OR vs IN 성능]의 가능한 복제본 (http://stackoverflow.com/questions/782915/mysql-or-vs-in-performance) –

답변

125

나는 다음과 같은 간의 성능 차이를 알고 싶어요 가정

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

+15

옵티 마이저의 염 가치가있는 경우 옵티마이 저를 수행해야합니다. –

+21

@inflagranti : 안타깝게도 최적화 프로그램이 완벽하지 않습니다. 최적화 도구는 매우 복잡한 프로그램이며 각 구현에는 고유 한 강점과 약점이 있습니다. 그래서 특정 구현에 대해 프로필을 작성해야한다고 말합니다. 나는'IN' 메쏘드의 여분의 구조가 가능한 많은'OR' 절들보다 최적화하는 것이 더 쉽다고 생각합니다. 'OR' 방법이 더 빠른 엔진이 있다면 놀랄 것입니다. 그러나 OR이 느릴 때가 있다는 것에 놀랄 것은 없습니다. –

+2

@ MarkByers 최적화 프로그램은 항상 여러 개의 'OR'을 'IN'으로 대체 할 수 없습니까? – mayu

1

OR은 비교할 값이 적을 때 (읽기 쉽도록) 의미가 있습니다. IN은 유용합니다. 동적 소스가있는 경우에는 값을 비교할 수 있습니다.

또 다른 대안은 JOIN을 임시 테이블과 함께 사용하는 것입니다.
필요한 인덱스가 있으면 성능이 문제가 될 것이라고 생각하지 않습니다.

26

가장 좋은 방법은 실행 계획입니다.


나는 오라클와 그것을 시도, 그것은 동일했다. 쿼리 IN를 사용

CREATE TABLE performance_test AS (SELECT * FROM dba_objects); 

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

에도 불구하고, 실행 계획은 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에서 어떤 일이 발생합니까? ? 오라클이 MySQL과 동일한 바이너리 검색 최적화를 수행 할 수 없거나 두 경우 모두 수행 할 수 있는지 알고 있습니까? –

+2

@Mark Byers : 10 개의 값으로 같은 쿼리를 시도했지만 결과는 같습니다. 참고로, 옵티마이 저가 내 값을 알파벳 순서로 사용했습니다. 오라클이 필터의 내부 최적화를 수행했다면 놀라지 않을 것입니다 ... –

+5

오라클은 또한 'INLIST ITERATOR'연산을 사용합니다.이 연산은 사용할 수있는 인덱스가 있다면 선택합니다. 그래도 시도해 보면 IN과 OR 모두 같은 실행 계획으로 끝납니다. –

5

나는 오라클이 효율적이지 않은 것을 (다른 쪽이든) 변환 할만큼 똑똑하다고 생각합니다. 그래서 대답은 차라리 각각의 가독성에 달려 있다고 생각합니다. (IN이 분명히 이긴다고 생각합니다)

5

OR 연산자는 IN 조건보다 훨씬 복잡한 계산 과정이 필요합니다. 에서.

OR과 함께 사용할 수 있지만 IN과 호환되지 않는 것은 다음과 같습니다 : greater. 크거나 같음, 작음, 작거나 같음, LIKE 및 일부는 ORACLE REGISP_LIKE와 같습니다. 조건이 항상 동일한 값을 비교하지 않을 수도 있습니다.

쿼리 최적화 프로그램의 경우 동일한 값에서 = 연산자를 사용하여 여러 조건에서 OR 연산자를 정의하는 구문이므로 IN 연산자를보다 쉽게 ​​관리 할 수 ​​있습니다. OR 연산자를 사용하면 옵티마이 저가 동일한 값에서 = 연산자를 항상 사용하고 있다고 생각하지 않을 수 있습니다. 더 깊고 복잡한 작업을 수행하지 않으면 아마도 = 관련된 모든 조건에서 동일한 값을 갖는 연산자. 이미 언급 한 이진 검색과 같은 최적화 된 검색 방법을 결과적으로 제외시킵니다.

[편집] 아마 최적화 프로그램이 최적화 된 IN 평가 프로세스를 구현하지 못할 수도 있지만 데이터베이스 업그레이드를 통해 한 번만 수행되는 것을 제외하지는 않습니다. 따라서 OR 연산자를 사용하면 최적화 된 정교화가 사용되지 않습니다.

1

다수의 OR (350)에서 SQL 쿼리를 수행했습니다. 포스트 그레스는 그것을한다 437.80ms.

Use OR

지금에 사용 :

Use IN

23.18ms는

+1

IN 절에 하위 쿼리를 사용 했으므로 그와 완전히 똑같은 것은 아닙니다. – gliljas

관련 문제