해결된 질문
24.08.04 16:36 작성
·
78
0
안녕하세요.
강의에서는
LEFT JOIN ...
ON ...
하고 나서 WHERE type1='Grass'으로 먼저 필터링을 하신 것 같은데요!
아래 처럼 GROUP BY - HAVING으로 해도 결과는 동일한데,
GROUP BY 보다 WHERE를 먼저 했을 때 수행 속도 등의 이득이 있는지 궁금합니다!
SELECT
type1,
COUNT(type1) AS pokemon_cnt
FROM (
SELECT
id,
trainer_id,
pokemon_id,
status
FROM
`basic.trainer_pokemon`
WHERE
status IN ('Active', 'Training')
) AS tp
LEFT JOIN `basic.pokemon` AS p
ON tp.pokemon_id = p.id
GROUP BY
type1
HAVING
type1 = 'Grass'
답변 1
0
2024. 08. 04. 23:15
HTCho1님 안녕하세요!
작성해주신 것은 HAVING을 쓰신거고, 저는 WHERE 조건을 사용했어요. 지금 저희 데이터셋에선 크게 차이가 나진 않지만 데이터가 많을 때는 WHERE 조건이 더 빠릅니다.
그 이유는 WHERE이 연산의 앞쪽에 위치합니다. FROM 절에 있는 데이터에서 필터링을 합니다. 데이터를 한번 줄이고, GROUP BY를 하는 것이죠. 반면에 작성해주신 쿼리는 데이터를 줄이지 않고 마지막에 HAVING으로 데이터를 필터링합니다. 앞에서 데이터를 줄이면 뒤 연산을 할 때 더 효율적으로 접근할 수 있어요. 데이터를 처리하는 흐름이 존재하기 때문에 앞에서 연산을 줄이는 것이 연산 관점에서 효율적입니다.
이것을 확인하기 위해 각 쿼리를 실행해보고, 실행 세부 정보를 확인해볼게요.
제가 강의에서 작성한 쿼리
SELECT
-- tp.*,
p.type1,
COUNT(tp.id) AS pokemon_cnt
FROM (
SELECT
id,
trainer_id,
pokemon_id,
status
FROM basic.trainer_pokemon
-- Table "trainer_pokemon" must be qualified with a dataset (e.g. dataset.table). => basic 명시 안함
WHERE
status IN ("Active", "Training")
) AS tp
LEFT JOIN basic.pokemon AS p
ON tp.pokemon_id = p.id
WHERE
type1 = "Grass"
GROUP BY
type1
HTCho1님이 작성한 쿼리
SELECT
type1,
COUNT(type1) AS pokemon_cnt
FROM (
SELECT
id,
trainer_id,
pokemon_id,
status
FROM
`basic.trainer_pokemon`
WHERE
status IN ('Active', 'Training')
) AS tp
LEFT JOIN `basic.pokemon` AS p
ON tp.pokemon_id = p.id
GROUP BY
type1
HAVING
type1 = 'Grass'
제가 작성한 쿼리의 실행 세부 정보는 다음과 같습니다(A라고 지칭할게요)
HTCho1님의 쿼리 실행 세부 정보는 다음과 같습니다(B라고 지칭할게요)
이 부분을 자세하게 알아야 하는 것은 아니고 간단히 보셔도 됩니다. A는 경과 시간이 353밀리초, B는 484밀리초입니다. 경과 시간은 A가 더 적게 소요되었어요. 그리고 슬롯 시간은 쿼리에서 연산 등이 실행될 때 사용됩니다. A는 51밀리초, B는 210밀리초. 셔플 바이트는 데이터를 셔플하는 개념인데 이 값이 클수록 데이터가 많다고 보시면 될 것 같아요.
관련해서 아래 문서를 보시면 최적화에 대해 더 아실 수 있을거에요.
https://cloud.google.com/bigquery/docs/best-practices-performance-compute?hl=ko
또 궁금한 것이 있으면 말씀해주셔요!