[sql] SQL WHERE 절에서 IN 대 OR

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

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



답변

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

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


답변

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


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


답변

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

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

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

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


답변

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


답변

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

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


답변

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

OR 사용

이제 IN을 사용하십시오.

IN 사용

23.18ms


답변