큰 데이터베이스를 다룰 때 더 나은 성능을 보 입니까 , IN
아니면 OR
SQL 절에서 Where
?
그들이 실행되는 방식에 차이가 있습니까?
큰 데이터베이스를 다룰 때 더 나은 성능을 보 입니까 , IN
아니면 OR
SQL 절에서 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 % 느립니다. 용어를 더 추가하면 차이가 커집니다. 결과는 다른 데이터베이스 및 다른 데이터에 따라 달라질 수 있습니다.
IN
메소드 의 추가 구조로 인해 관련 OR
절 전체를 최적화하는 것이 더 쉽다고 생각 합니다. OR
방법이 더 빠른 엔진이 있다면 놀랄 것입니다. 그러나 OR이 느릴 때가 있습니다.
OR
로들 IN
?
확인하는 가장 좋은 방법은 실행 계획을 보는 것입니다.
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')
INLIST ITERATOR
사용할 수있는 인덱스가있는 경우 선택 하는 작업이 있습니다. 그럼에도 불구하고, 나는 그것을 밖으로 시도, 두 때 IN
와 OR
동일한 실행 계획을 끝낸다.
OR 연산자는 IN과 같을뿐만 아니라 많은 조건을 허용하므로 IN 구문보다 훨씬 복잡한 평가 프로세스가 필요합니다.
다음은 OR과 함께 사용할 수 있지만 IN과 호환되지 않는 것과 비슷합니다. 크거나 같음, 작음, 작음 또는 같음, LIKE 및 오라클 REGEXP_LIKE와 비슷합니다. 또한 조건이 항상 동일한 값을 비교하지는 않을 수도 있습니다.
쿼리 최적화 프로그램의 경우 IN 연산자를 관리하기가 더 쉽습니다. 동일한 값에 = 연산자를 사용하여 여러 조건에서 OR 연산자를 정의하는 구문 만 있기 때문입니다. OR 연산자를 사용하는 경우 옵티마이 저는 항상 같은 값으로 = 연산자를 사용한다고 생각하지 않을 수 있으며 더 깊고 훨씬 더 복잡한 정교화를 수행하지 않으면 아마도 = 이미 언급 된 이진 검색과 같은 최적화 된 검색 방법을 배제하여 관련된 모든 조건에서 동일한 값에 대한 연산자.
[편집] 아마 옵티마이 저는 최적화 된 IN 평가 프로세스를 구현하지 않을 수도 있지만 (데이터베이스 버전 업그레이드시) 한 번만 발생할 수 있다는 것을 배제하지는 않습니다. 따라서 OR 연산자를 사용하면 최적화 된 정교화가 사용되지 않습니다.
많은 OR (350)에서 SQL 쿼리를 수행했습니다. Postgres는 437.80ms를 수행합니다 .
이제 IN을 사용하십시오.
23.18ms