sub_title
 MySQL
제   목 MySQL IN subquery 성능. IN sub query는 가급적 사용을 피합시다!
작성자 진짜고구마 등록일 2017-08-21 00:47:14 조회수 5,852

들어가며

다른 RDBMS는 모르겠지만 MySQL에서 IN subquery의 성능은 별로 좋지를 못하다. 본 글에서는 IN Subquery의 작동 방식을 살펴볼 것이다.

Data는 TPC-H 벤치마크 데이터를 이용하여 실험하였다. TPC-H 데이터를 MySQL에 Loading하는 것은 필자가 작성한 글을 보기 바란다.

본 글은 MySQL 5.5를 기준으로 작성되었다. MySQL 5.6에서는 subquery materialization을 이용하여 IN subquery의 성능이 향상되었다. MySQL 5.6의 IN () 성능 측정 결과는 다른 포스트에 정리할 예정이다.

IN subquery는 속도가 느리다

다음과 같이 30만명의 고객(customer)와 300만개의 주문(orders)가 존재한다.

mysql> SELECT COUNT(*) FROM customer;
+----------+
| COUNT(*) |
+----------+
|   300000 |
+----------+
1 row in set (0.00 sec)
 
mysql> SELECT COUNT(*) FROM orders;
+----------+
| COUNT(*) |
+----------+
|  3000000 |
+----------+
1 row in set (0.46 sec)

우선 2명의 고객 정보를 조회했다.

mysql> SELECT c_custkey FROM customer LIMIT 2;
+-----------+
| c_custkey |
+-----------+
|        29 |
|        48 |
+-----------+
2 rows in set (0.00 sec)

이들이 주문한 주문 정보를 조회하는 것은 다음과 같이 조회하면 된다. o_custkey가 INDEX로 걸려있기 때문에 수행 속도가 무척 빠르다.

mysql> SELECT SQL_NO_CACHE o_orderkey FROM orders WHERE o_custkey IN (29, 48);
+------------+
| o_orderkey |
+------------+
|    1572644 |
|    2773829 |
|    3440902 |
|    5779717 |
|    6144551 |
|    9493348 |
|    9974083 |
+------------+
7 rows in set (0.00 sec)

하지만, 쿼리를 다음과 같이 변경하면 동일한 결과가 출력되지만 3.12초나 걸린다!

mysql> SELECT SQL_NO_CACHE o_orderkey
    -> FROM orders
    -> WHERE o_custkey IN
         (SELECT c_custkey FROM customer WHERE c_custkey IN (29, 48));
+------------+
| o_orderkey |
+------------+
|    1572644 |
|    2773829 |
|    3440902 |
|    5779717 |
|    6144551 |
|    9493348 |
|    9974083 |
+------------+
7 rows in set (3.12 sec)

어떻게 된 것일까?

 

 

출처: http://jason-heo.github.io/mysql/2014/05/22/avoid-mysql-in.html

 
0
    
 
0
        list
 
※ 짧은 댓글일수록 예의를 갖추어 작성해 주시기 바랍니다.
line
reply cancel
 
번호 제목 글쓴이 추천 조회 날짜
49  MariaDB 10의 NoSQL 기능과 MySQL의 Json 관련 UDF   member 달콤한수 2 / 0 6916 2017-11-29
48  MySQL은 공짜가 아니다   member 진짜고구 3 / 1 5655 2017-08-24
47  MySql 문자열 함수   member 진짜고구 0 / 0 3938 2017-08-24
46  MySQL IN subquery 성능. IN sub query는 가급적 사용을 피합시다!   member 진짜고구 0 / 0 5852 2017-08-21
45  [MYSQL] 가져온 값을 조건에 따라 값 바꾸기(case - when - end 문)    member 진짜고구 0 / 0 3602 2017-08-21
44  MySQL 가져온 데이터 삽입하기(SELECT 하면서 INSERT하기)   member 높이뜬새 1 / 1 20481 2017-08-19
43  터미널에서 접속해 MySQL 테이블 내용을 볼려고 할때 한글이 깨진다면!!   member 높이뜬새 0 / 0 2107 2017-04-04
42  MySQL 문자열 길이 구하기   member 높이뜬새 2 / 0 15778 2017-04-04
41  MySQL 사용자 권한설정 (grant 명령어) 이미지   member 높이뜬새 1 / 0 11128 2016-10-23
40  MySQL 컬럼중 가장 큰값 가져오기 이미지   member 높이뜬새 1 / 0 5768 2016-08-20
39  MySQL 오늘기준으로 최근 한달 동안 데이터 가져오기   member 높이뜬새 2 / 2 15726 2016-08-09
38  MySQL 원격서버로 덤프파일 복원하기   member 높이뜬새 1 / 0 5763 2016-04-27
37  MySQL에서 특정 문자열만 변경하기 이미지   member 높이뜬새 0 / 0 10718 2016-01-23
36  MySQL 이번주의 요일별 날짜를 가져오기 이미지   member 높이뜬새 0 / 0 10965 2016-01-20
35  MySQL 요일 구하기 이미지   member 높이뜬새 3 / 0 22239 2016-01-18
34  MySQL 문자형 컬럼에 숫자가 포함된 데이터 가져오기   member 높이뜬새 1 / 0 6418 2015-06-29
33  MySQL 바이너리 검색시 인덱스를 타게하기   member 높이뜬새 10 / 0 6783 2015-06-29
32  MySQL 컬럼의 중복 레코드 수를 구하기   member 높이뜬새 2 / 0 2977 2015-06-29
31  MySQL 자동증가, auto increment 값 초기화 하기   member 높이뜬새 3 / 0 6199 2015-06-29
30  MySQL 테이블 복사하기 이미지   admin 웹마당넷 4 / 0 9264 2015-06-28
29  MySQL 필드의 결합   admin 웹마당넷 1 / 0 3750 2015-06-26
28  MySQL select 출력 값을 text파일로 만들기 이미지   admin 웹마당넷 3 / 0 6143 2015-06-26
27  MySQL 에서 IF문 사용하기   member 높이뜬새 23 / 3 149905 2010-03-08
26  MySQL 날짜 차이 구하기   member 높이뜬새 6 / 1 23026 2010-01-25
25  MySQL 특정 테이블만 백업하기   member 높이뜬새 11 / 0 49956 2010-01-06
write
[2] button