Database ( DB )/Database

[MySQL] COUNT의 잘못된 인식과 속도 차이

노루아부지 2019. 8. 10. 22:20
반응형

일반 SQL 질의의 SELECT 절에의 *는 모든 컬럼을 가지고 오기 때문에 

 

필요한 컬럼만 가지고 오는 SELECT 절에 비해 속도가 느리고 불필요한 자원을 

 

낭비한다는 사실은 모두가 알고 있을 것입니다. 

 

그렇기 때문에 이러한 것을 똑같이 생각함으로 인해 집계함수의 COUNT에 대한 COUNT(*) 와 

 

COUNT(컬럼)에 대한 잘못된 인식과 SQL 질의를 실행하여 DB의속도를 느리게 할 수 있는 원인이 될 수 있습니다. 

 

일반 SQL질의와 다르게 COUNT 집계함수에서의 *의 역할은 다른 역할을 수행하고 있습니다. 

 

* MySQL COUNT 함수의 역할을 보면 

 

COUNT(*) : 단순 행을 세는 역할을 합니다. (MySQL 내부적으로 데이터를 읽지않고 행의 갯수만 흝고 지나간다는 뜻을 말합니다.) 

 

COUNT(컬럼) : 행의 값을 세는 역할을 합니다.(데이터를 읽는다는 뜻이 되겠지요) 

 

자 그럼, 컬럼이 VARCHAR(50) 형태의 데이터가 100만건이 있다는 가정하에 실행계획 및 질의를 실행에 보도록 하겠습니다. 

 

* 실행계획 

 

1) COUNT(*) : 우선 단순 행을 세는 COUNT(*)의 실행계획을 보도록 하겠습니다. 

 

id select_type table type possible_keys key key_len ref rows Extra 

1 SIMPLE Select tables optimized away 

 

Select tables optimized away : 인덱스, 또는 MyISAM용 COUNT(*)을 사용하되 GROUP BY 구문은 사용하지 않은 채로 처리된 집단 함수(MIN(), MAX())만을 가지고 있음. 

 

2) COUNT(컬럼) : 데이터를 읽고 지나가는 COUNT(컬럼)의 실행계획을 보도록 하겠습니다. 

 

id select_type table type possible_keys key key_len ref rows Extra 

1 SIMPLE performance1 ALL 1000000

 

실행계획을 보면 알듯이 type을 보면 알 수 있듯이 ALL로 전체를 스캔하는 것을 알 수 있수 있을 것입니다. 

 

3) COUNT(DISTINCT(컬럼)): DISTINCT에 데이터를 읽고 지나가는 COUNT(DISTINCT(컬럼))의 실행계획을 보도록 하겠습니다. 

 

id select_type table type possible_keys key key_len ref rows Extra 

1 SIMPLE performance1 ALL 1000000

 

COUNT(DISTINCT(컬럼))도 type을 보면 알 수 있듯이 ALL로 전체를 스캔하는 것을 알 수 있을 것입니다. 

 

 

실행계획을 봤으니 SQL질의를 실행하여 실행시간을 비교해 보도록 하겠습니다. 

 

* 실행결과를 종합해 보면 

 

1) COUNT(*) : 0:00:00.029 

2) COUNT(컬럼) : 0:00:00.201 

3) COUNT(DISTINCT(컬럼)) : 0:00:02.413 

 

COUNT(DISTINCT(컬럼))  < COUNT(컬럼) < COUNT(*) 순입니다. 

 

그렇습니다. 불필요한 데이터를 셀 필요없이 행의 갯수만 얻고 싶다면 당연히 * 쓰는게 훨씬 속도 

 

가 빠르다는 사실을 알 수 있을 것을 것입니다. 

 

그러면 '혹시 컬럼에 인덱스를 걸어주면 데이터를 세더라도 count(*)보다 빠르지 않을까?' 라는 생각이 문득 들어서 

 

컬럼 하나에 인덱스를 걸고 인덱스를 타게 해서 질의를 실행하여 비교해 보도록 하였습니다. 

 

* 실행계획 

 

1) COUNT(*) 

 

id select_type table type possible_keys key key_len ref rows Extra 

1 SIMPLE Select tables optimized away 

 

2) COUNT(컬럼) 

 

id select_type table type possible_keys key key_len ref rows Extra 

1 SIMPLE performance2 index index 153 1000000 Using index 

 

3) COUNT(DISTINCT(컬럼)) 

 

id select_type table type possible_keys key key_len ref rows Extra 

1 SIMPLE performance2 index index 153 1000000 Using index 

 

 

* 실행결과를 다시 종합해보면 

 

1) COUNT(*) : 0:00:00.054 

2) COUNT(컬럼) : 0:00:00.592 

3) COUNT(DISTINCT(컬럼)) : 0:00:02.955 

 

그렇습니다. 실행결과를 보면 인덱스 거는거에 상관없이 COUNT(*)이 가장 빠르게 질의를 수행한다는 것을 알 수 있 

 

을 것입니다. 누구나 다 아는 사실이지만, 참고가 될 수 있도록 글을 기재합니다. 

 

[ 실행환경 ] 

 

MySQL Version : 5.1.41-community 

 

테이블 형태 : MyISAM 

 

컬럼 형태 : varchar(50)

 

 

 

출처 : https://www.phpschool.com/gnuboard4/bbs/board.php?bo_table=tipntech&wr_id=77484

728x90
반응형
loading