SQL/MySQL

MySQL 실제 실행계획

스윗보스 2020. 10. 30. 16:50

 

오라클은 SQL 성능에 대해서 다양한 방법으로 측정이 가능합니다. 이로 인해, 튜닝도 비교적 쉽게 할 수 있습니다. 반면에 MySQL은 성능 측정이 쉽지 않습니다.

 

지금까지 MySQL의 실행계획을 확인하기 위해서는 EXPLAIN 과 함께 SQL을 실행하면 됩니다. 하지만 EXPLAIN으로 확인할 수 있는 정보는 너무 제한적입니다.

MySQL8 에서는 EXPLAIN에 ANALYZE 옵션을 지정할 수 있습니다. 

dev.mysql.com/doc/refman/8.0/en/explain.html

 

MySQL :: MySQL 8.0 Reference Manual :: 13.8.2 EXPLAIN Statement

13.8.2 EXPLAIN Statement {EXPLAIN | DESCRIBE | DESC} tbl_name [col_name | wild] {EXPLAIN | DESCRIBE | DESC} [explain_type] {explainable_stmt | FOR CONNECTION connection_id} {EXPLAIN | DESCRIBE | DESC} ANALYZE [FORMAT = TREE] select_statement explain_type:

dev.mysql.com

 

제가 가지고 있는 MySQL 테스트 DB에서 기존 방법으로 EXPLAIN 만 사용해서 실행계획을 확인해 보겠습니다.

(테스트 DB는 오라클 기준으로 쓰여진 책 'SQL BOOSTER'의 DB를 MySQL로 컨버젼한 DB입니다.)

 

EXPLAIN
SELECT  COUNT(*)
FROM    T_ORD_BIG T1
        INNER JOIN M_CUS T2
          ON  (T2.CUS_ID = T1.CUS_ID)
WHERE   T1.ORD_YMD LIKE '201703%';

# 결과
id   select_type   table   partitions   type    possible_keys                                             key             key_len   ref                         rows    filtered   Extra                      
==== ============= ======= ============ ======= ========================================================= =============== ========= =========================== ======= ========== ========================== 
1    SIMPLE        T2      None         index   PRIMARY                                                   FK_CUS_1        163       None                        90      100.0      Using index                
1    SIMPLE        T1      None         ref     X_T_ORD_BIG_1,X_T_ORD_BIG_3,X_T_ORD_BIG_4,X_T_ORD_BIG_5   X_T_ORD_BIG_4   162       db_mysqlbooster.T2.CUS_ID   34394   13.33      Using where; Using index   

 

오라클만 사용했던 사람이라면, 이해가 쉽지 않은 구조의 실행계획입니다. 이번에는 EXPLAIN ANALYZE 로 실행계획을 확인해 보겠습니다.

EXPLAIN ANALYZE
SELECT  COUNT(*)
FROM    T_ORD_BIG T1
        INNER JOIN M_CUS T2
          ON  (T2.CUS_ID = T1.CUS_ID)
WHERE   T1.ORD_YMD LIKE '201703%';

# 결과
-> Aggregate: count(0)  (actual time=5384.902..5384.902 rows=1 loops=1)
     -> Nested loop inner join  (cost=444232.85 rows=412658) (actual time=21.379..5358.471 rows=185000 loops=1)
         -> Index scan on T2 using FK_CUS_1  (cost=10.00 rows=90) (actual time=1.522..3.185 rows=90 loops=1)
         -> Filter: (t1.ORD_YMD like '201703%')  (cost=1501.46 rows=4585) (actual time=23.675..59.104 rows=2056 loops=90)
             -> Index lookup on T1 using X_T_ORD_BIG_4 (CUS_ID=t2.CUS_ID)  (cost=1501.46 rows=34394) (actual time=0.437..50.395 rows=33856 loops=90)
 

마치 오라클의 실행계획처럼 자세하고, Tree형태로 실행계획이 나오고 있습니다.! 앞으로는 이 방법을 사용해 MySQL 튜닝을 진행해야 겠네요. 물론 MySQL 버젼에 따라 지원되지 않을 수 있습니다.