developer tip

SQL 성능 UNION 대 OR

copycodes 2020. 12. 12. 11:28
반응형

SQL 성능 UNION 대 OR


난 그냥 최적화 기사의 일부를 읽고 시키고 말았다 다음 문의 :

ORwith a를 사용하는 SQL replace 문을 사용할 때 UNION:

select username from users where company = ‘bbc’ or company = ‘itv’;

에:

select username from users where company = ‘bbc’ union
select username from users where company = ‘itv’;

빠른에서 EXPLAIN:

사용 OR:

여기에 이미지 설명 입력

사용 UNION:

여기에 이미지 설명 입력

이것은 두 배의 작업을 의미 UNION하지 않습니까?

UNION특정 RDBMS 및 특정 테이블 스키마에 대해 성능이 더 우수 할 수 있다는 점을 높이 평가하지만 저자가 제안한 것처럼 이것은 절대적으로 사실 이 아닙니다 .

질문

내가 잘못?


읽은 기사가 나쁜 예를 사용했거나 그 요점을 잘못 해석했습니다.

select username from users where company = 'bbc' or company = 'itv';

이것은 다음과 동일합니다.

select username from users where company IN ('bbc', 'itv');

MySQL company은이 쿼리 대한 인덱스를 사용할 수 있습니다 . UNION을 할 필요가 없습니다.

더 까다로운 경우는 OR두 개의 다른을 포함 하는 조건 이있는 경우입니다 .

select username from users where company = 'bbc' or city = 'London';

에 인덱스가 company있고에 별도의 인덱스 가 있다고 가정 합니다 city. MySQL은 일반적으로 주어진 쿼리에서 테이블 당 하나의 인덱스 만 사용한다는 점을 감안할 때 어떤 인덱스를 사용해야합니까? 에 인덱스를 사용하는 경우 company에도 city런던이 있는 행을 찾기 위해 테이블 ​​스캔을 수행해야합니다 . 의 인덱스를 사용하는 경우 bbc 인 city행에 대해 테이블 ​​스캔을 수행해야합니다 company.

UNION용액이 케이스의 유형이다.

select username from users where company = 'bbc' 
union
select username from users where city = 'London';

이제 각 하위 쿼리는 검색에 색인을 사용할 수 있으며 하위 쿼리의 결과는 UNION.


익명의 사용자가 위의 답변에 대한 수정을 제안했지만 중재자가 수정을 거부했습니다. 편집이 아닌 주석이어야합니다. 제안 된 편집의 주장은 UNION이 중복 행을 제거하기 위해 결과 집합을 정렬해야한다는 것입니다. 이로 인해 쿼리 실행 속도가 느려지므로 인덱스 최적화가 세척됩니다.

내 응답은 인덱스가 UNION이 발생하기 전에 결과 집합을 적은 수의 행으로 줄이는 데 도움이된다는 것입니다. UNION은 실제로 중복을 제거하지만 그렇게하려면 작은 결과 집합 만 정렬하면됩니다. WHERE 절이 테이블의 상당 부분과 일치하는 경우가있을 수 있으며 UNION 중 정렬은 단순히 테이블 스캔을 수행하는 것만 큼 비용이 많이 듭니다. 그러나 인덱싱 된 검색에 의해 결과 집합이 줄어드는 것이 더 일반적이므로 정렬은 테이블 스캔보다 훨씬 저렴합니다.

차이는 표의 데이터와 검색되는 용어에 따라 다릅니다. 주어진 쿼리에 대한 최상의 솔루션을 결정하는 유일한 방법 은 MySQL 쿼리 프로파일 러 에서 두 방법을 모두 시도 하고 성능을 비교하는 것입니다.


그것들은 같은 쿼리가 아닙니다.

저는 MySQL에 대한 경험이 많지 않으므로 쿼리 최적화 프로그램이 무엇을하는지,하지 않는지 잘 모르겠지만 여기에 일반적인 배경 (주로 ms SQL 서버)에서 내 생각이 있습니다.

일반적으로 쿼리 분석기는 위의 두 쿼리를 가져 와서 (동일한 경우) 정확히 동일한 계획을 만들 수 있으므로 중요하지 않습니다. 이러한 쿼리간에 성능 차이가 없다고 생각합니다 (동등 함).

select distinct username from users where company = ‘bbc’ or company = ‘itv’;

select username from users where company = ‘bbc’ 
union
select username from users where company = ‘itv’;

Now, the question is, would there be a difference between the following queries, of which I actually don't know, but I would suspect that the optimizer would make it more like the first query

select username from users where company = ‘bbc’ or company = ‘itv’;

and

select username from users where company = ‘bbc’ 
union all
select username from users where company = ‘itv’;

It depends on what the optimizer ends up doing based on the size of the data, indexes, software version, etc.

I would guess that using OR would give the optimizer a better chance at finding some efficiencies, since everything is in a single logical statement.

Also, UNION has some overhead, since it creates a reset set (no duplicates). Each statement in the UNION should execute pretty quickly if company is indexed... not sure it'd really be doing double the work.

Bottom line

Unless you really have a burning need to squeeze every bit of speed out of your query, it's probably better to just go with the form that best communicates your intention... the OR

Update

I also meant to mention IN. I believe the following query will give better performance than the OR (it's also the form I prefer):

select username from users where company in ('bbc', 'itv');


In almost all cases, the union or union all version is going to do two full table scans of the users table.

The or version is much better in practice, since it will only scan the table once. It will also use an index only once, if available.

The original statement just seems wrong, for just about any database and any situation.


Bill Karwin의 대답은 매우 옳습니다. OR 문의 두 부분에 자체 인덱스가있는 경우 결과의 작은 하위 집합이 있으면 정렬하고 중복을 제거하는 것이 더 쉽기 때문에 통합을 수행하는 것이 좋습니다. 총 비용은 하나의 인덱스 만 사용하고 (하나의 열에 대해) 다른 열에 대해 테이블 ​​스캔을 사용하는 것보다 거의 적습니다 (mysql은 하나의 열에 대해 하나의 인덱스 만 사용하기 때문입니다).

그것은 테이블의 구조와 일반적으로 필요에 따라 다르지만 큰 테이블에서 결합하면 더 나은 결과를 얻었습니다.

참고 URL : https://stackoverflow.com/questions/13750475/sql-performance-union-vs-or

반응형