MySQL GROUP BY 설명: 구문, 예제, HAVING, ORDER BY 및 성능 최적화

1. 소개: GROUP BY 개요

데이터베이스에서 대규모 데이터를 다룰 때, GROUP BY 절은 데이터를 효율적으로 집계하고 정리하는 강력한 도구입니다. GROUP BY는 특정 열을 기반으로 레코드를 그룹화하고 각 그룹에 대해 집계를 수행하는 데 사용됩니다. 예를 들어, 각 제품 카테고리별 총 판매액을 계산하려면 이 절을 사용하면 원하는 결과를 쉽게 가져올 수 있습니다.

GROUP BY 절을 사용하면 데이터를 시각적으로 이해하기 쉬운 형식으로 정리할 수 있으며, SUM, COUNT, AVG와 같은 집계 함수를 사용하여 더 깊은 분석을 수행할 수 있습니다.

2. GROUP BY의 기본 사용법

GROUP BY 절은 지정된 열을 기반으로 데이터를 그룹화하고 각 그룹에 대해 집계를 수행할 수 있게 합니다. 이를 통해 특정 카테고리나 조건에 기반한 요약 및 통계를 쉽게 생성할 수 있습니다.

기본 구문

SELECT column_name, aggregate_function(column_name)
FROM table_name
GROUP BY column_name;

예제

각 제품 카테고리별 총 판매액을 계산하려면 다음 쿼리를 작성할 수 있습니다:

SELECT product_category, SUM(sales_amount)
FROM sales
GROUP BY product_category;

이 쿼리는 각 제품 카테고리별 총 판매액을 계산합니다.

예제 결과

product_categorySUM(sales_amount)
Electronics100,000
Food50,000
Clothing75,000

3. GROUP BY와 집계 함수 결합

GROUP BY 절을 집계 함수와 결합하면 데이터를 그룹화하고 각 그룹의 통계 정보를 얻을 수 있습니다. MySQL에서 자주 사용되는 일반적인 집계 함수는 다음과 같습니다:

  • SUM() : 숫자 값의 총계를 계산합니다.
  • COUNT() : 레코드 수를 계산합니다.
  • AVG() : 숫자 데이터의 평균 값을 계산합니다.
  • MAX() : 최대 값을 가져옵니다.
  • MIN() : 최소 값을 가져옵니다.

샘플 쿼리

각 제품 카테고리별 총 판매액과 거래 수를 모두 가져오려면 다음 쿼리를 작성할 수 있습니다:

SELECT product_category, SUM(sales_amount), COUNT(*)
FROM sales
GROUP BY product_category;

이 쿼리는 각 product_category에 대한 총 판매액과 거래 수를 가져옵니다.

4. HAVING 절을 사용한 필터링

HAVING 절은 GROUP BY 절에 의해 생성된 그룹화된 데이터에 추가 조건을 적용하는 데 사용됩니다. HAVING의 주요 특징은 집계 함수를 기반으로 필터링할 수 있다는 것입니다. 집계 전에 데이터를 필터링하는 WHERE 절과 달리, HAVING은 집계가 수행된 후 결과를 필터링합니다.

샘플 쿼리

예를 들어, 총 판매액이 1000을 초과하는 카테고리만 추출하려면 다음 쿼리를 작성할 수 있습니다:

SELECT product_category, SUM(sales_amount)
FROM sales
GROUP BY product_category
HAVING SUM(sales_amount) > 1000;

이 쿼리는 총 판매액이 1000을 초과하는 제품 카테고리만 가져옵니다.

5. GROUP BY와 ORDER BY 사용

GROUP BY 절을 사용하여 데이터를 그룹화한 후, ORDER BY 절을 사용하여 결과를 정렬할 수 있습니다. ORDER BY 절은 지정된 열을 기반으로 결과를 오름차순(ASC) 또는 내림차순(DESC)으로 정렬합니다.

샘플 쿼리

제품 카테고리를 총 판매액에 따라 내림차순으로 정렬하려면 다음 쿼리를 사용하세요:

SELECT product_category, SUM(sales_amount)
FROM sales
GROUP BY product_category
ORDER BY SUM(sales_amount) DESC;

이 쿼리는 총 판매액이 가장 높은 제품 카테고리부터 표시합니다.

6. 고급 GROUP BY 사용: WITH ROLLUP

WITH ROLLUP은 GROUP BY 절의 확장으로, 그룹화된 결과 외에 요약 행(총계 포함)을 자동으로 추가합니다. 이를 통해 그룹별 총계뿐만 아니라 전체 총계를 쉽게 얻을 수 있습니다. 특히 판매 보고서와 요약 보고서에 유용합니다.

샘플 쿼리

다음 쿼리는 각 도시별 총 판매액과 전체 총 판매액을 표시합니다:

SELECT city, SUM(sales_amount)
FROM sales
GROUP BY city WITH ROLLUP;

이 쿼리는 도시별 총 매출을 보여주며, 전체 매출의 총합도 포함합니다.

7. GROUP BY와 DISTINCT의 차이점

DISTINCTGROUP BY는 모두 데이터를 정리하는 데 사용되지만, 목적이 다릅니다. DISTINCT는 중복 레코드를 제거하고 고유한 값을 반환하는 반면, GROUP BY는 데이터를 그룹화하고 집계를 수행합니다.

샘플 쿼리 비교

고유한 제품 카테고리 목록을 가져오기 위해 DISTINCT를 사용하는 예시:

SELECT DISTINCT product_category
FROM sales;

제품 카테고리별 거래 수를 가져오기 위해 GROUP BY를 사용하는 예시:

SELECT product_category, COUNT(*)
FROM sales
GROUP BY product_category;

DISTINCT는 단순히 중복 데이터를 제거하는 반면, GROUP BY는 집계를 수행한다는 점이 두 방법의 큰 차이점입니다.

8. MySQL에서 GROUP BY 성능 최적화

대용량 데이터셋을 다룰 때, GROUP BY 절의 성능을 최적화하는 것은 매우 중요합니다. 대량의 데이터를 효율적으로 처리하려면 적절한 설정과 쿼리 최적화가 필요합니다.

1. 인덱스 사용

GROUP BY 절에 사용되는 컬럼에 인덱스를 생성하면 데이터 검색 및 그룹화 작업을 크게 빠르게 할 수 있습니다.

CREATE INDEX idx_category ON sales(product_category);

인덱스를 적절히 사용하면 성능이 크게 향상됩니다.

2. 메모리 설정 조정

MySQL에서 대용량 데이터셋을 처리할 때는 메모리 설정 최적화가 필수입니다. sort_buffer_sizetmp_table_size를 올바르게 구성하면 쿼리 성능이 향상됩니다.

SET GLOBAL sort_buffer_size = 2M;
SET GLOBAL tmp_table_size = 64M;

메모리에서 처리할 수 있는 데이터 양을 늘리면 디스크 쓰기가 감소하고 처리 시간이 단축됩니다.

3. 쿼리 단순화

복잡한 쿼리는 성능을 저하시킬 수 있습니다. 과도한 JOIN이나 서브쿼리 사용은 실행 속도를 늦추므로, 가능한 한 쿼리를 단순하게 유지하는 것이 중요합니다. 불필요한 컬럼이나 조건을 제거하면 실행 시간이 줄어듭니다.

4. 버전 종속 기능

MySQL 8.0부터는 기존의 정렬 기반 그룹화 외에 해시 기반 그룹화가 제공됩니다. 해시 기반 처리는 일반적으로 정렬 기반 방식보다 빠르며, 대용량 데이터셋을 다룰 때 성능을 크게 향상시킬 수 있습니다.

SET optimizer_switch = 'hash_join=on';

5. 쿼리 캐시 사용

MySQL 5.7 이하 버전을 사용 중이라면, 쿼리 캐시를 활성화하면 동일한 쿼리를 반복 실행할 때 성능이 개선됩니다.

SET GLOBAL query_cache_size = 16M;
SET GLOBAL query_cache_type = 1;

6. 파티셔닝 고려

MySQL의 파티셔닝 기능을 사용하면 대형 데이터베이스를 물리적으로 여러 파트로 나눌 수 있어, 쿼리 성능을 향상시킬 수 있습니다.

ALTER TABLE sales PARTITION BY RANGE (YEAR(sale_date)) (
    PARTITION p0 VALUES LESS THAN (2021),
    PARTITION p1 VALUES LESS THAN (2022),
    PARTITION p2 VALUES LESS THAN (2023)
);

9. 요약: GROUP BY 효과적인 활용

GROUP BY 절은 데이터를 그룹화하고 집계하는 데 매우 유용한 SQL 구문입니다. 이 글에서는 GROUP BY의 기본 사용법부터 HAVING 및 ORDER BY 절과 결합하는 방법, 그리고 WITH ROLLUP과 같은 고급 집계 기능까지 모두 다루었습니다.

또한 인덱스 활용, 메모리 설정 튜닝, 해시 기반 그룹화와 같은 MySQL 버전별 기능을 이용한 대용량 데이터셋 처리 성능 최적화 기법도 살펴보았습니다. 이러한 전략을 이해하면 대량 데이터를 다룰 때 쿼리 성능을 크게 향상시킬 수 있습니다.

또한, 우리는 쿼리 캐싱과 파티셔닝과 같은 고급 MySQL 기능을 논의하여 대규모 데이터 처리 효율성을 더욱 향상시킬 수 있습니다. 버전별 기능과 구성 설정을 적절히 활용함으로써 비즈니스 환경에서 데이터 분석을 간소화할 수 있습니다.