ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [MySQL] COUNT 쿼리와 숫자 타입에 대한 주의 사항
    카테고리 없음 2021. 7. 26. 15:30
    728x90
    반응형

    MySQL COUNT() 함수 정리

    COUNT 함수는 모두가 알고 있듯이 결과 레코드의 건수를 반환하는 함수입니다. COUNT() 함수는 컬럼이나 표현식을 인자로 받고, COUNT(*)와 같이도 사용할 수 있습니다. 여기서 *는 SELECT 절에 사용될 때처럼 모든 컬럼을 가져오라는 의미가 아니라 그냥 레코드 자체를 의미하는 것입니다.

     

    실제로 COUNT()이라고 해서 레코드의 모든 컬럼을 읽는 형태로 처리하지는 않습니다. 그래서 굳이 COUNT(id), COUNT(1) 같이 사용하지 않아도 됩니다. COUNT()와 비슷한 속도로 처리된다고 합니다. (오.. 뭔가 차이가 있을 줄 알았지만 차이가 없다니~!!)

    MyISAM 스토리지 엔진을 사용하는 테이블은 항상 테이블의 메타 정보에 전체 레코드 건수를 관리하고 있습니다.

    SELECT COUNT(*) FROM gyunny

    위와 같은 쿼리는 MySQL 서버가 실제 레코드 건수를 세어 보지 않아도 바로 결과를 반환할 수 있기 때문에 빠르게 처리 됩니다. 하지만 WHERE 조건이 있는 COUNT(*) 쿼리는 그 조건에 일치하는 레코드를 읽어 보지 않는 이상 알 수 없으므로 일반적인 DBMS와 같이 처리 됩니다.

     

    MyISAM 이외의 스토리지 엔진을 사용하는 테이블에서는 WHERE 조건이 없는 COUNT(*) 쿼리라고 하더라도 직접 데이터나 인덱스를 읽어야만 레코드 건수를 가져올 수 있기 때문에 큰 테이블에서 COUNT() 함수를 사용하는 작업은 주의해야 합니다.
    (저는 MySQL InnoDB를 대부분 사용하기에 잘 알아두어야 할 거 같은 내용이네요!)



     

    COUNT 쿼리에 대한 오해

    많은 사용자들이 일반적으로 컬럼의 값을 SELECT 하는 쿼리보다 COUNT() 쿼리가 훨씬 빠르게 실행될 것이라고 생각할 때가 많습니다. 하지만 인덱스를 제대로 사용하도록 튜닝하지 못한 COUNT() 쿼리는 페이징해서 데이터를 가져오는 쿼리보다 몇 배 또는 몇십 배 더 느리게 실행될 수도 있습니다.
    COUNT(*) 쿼리도 많은 부하를 일으키기 때문에 주의 깊게 작성해야 합니다.



     

    MySQL 숫자 주의 사항

    문자열 형태로 따옴표를 사용하더라도 비교 대상이 숫자 값이거나 숫자 타입의 컬럼이면 MySQL 서버가 문자열 값을 숫자 값으로 자동 변환해줍니다.


    하지만 이처럼 숫자 값과 문자열 값을 비교할 때는 한 가지 주의해야 할 사항이 있습니다.

    SELECT * FROM tab_test WHERE number_column='10001';
    SELECT * FROM tab_test WHERE string_column='10001';

    MySQL은 숫자 타입과 문자열 타입 간의 비교에서 숫자 타입을 우선시하므로 문자열 값을 숫자 값으로 변환한 후 비교를 수행합니다.

    • 첫 번째 쿼리를 보면 숫자 컬럼에 문자열을 비교하고 있는데 상수값 하나만 문자열에서 숫자로 변환하므로 성능과 관련된 문제가 발생하지 않습니다.
    • 두 번째 쿼리를 보면 주어진 상수값이 숫자 값인데 비교되는 컬럼은 문자열 컬럼이빈다. 이 때 MySQL은 문자열 컬럼을 숫자로 변환해서 비교합니다. 즉, string_column 컬럼의 모든 문자열 값을 숫자로 변환해서 비교를 수행해야 하므로 string_column에 인덱스가 있다 하더라도 이를 이용하지 못합니다.

     

    즉, 원칙적으로 숫자 값은 숫자 타입의 컬럼에만 저장해야 합니다.

    반응형

    댓글

Designed by Tistory.