Engine Atlas

Cardinality & Histograms

예상 행 수는 왜 실제와 다를까
MySQL 8.4.102026-07-13
English
학습 안내

이 Lab에서 답할 질문

같은 query와 실제 rows를 두고 statistics state가 optimizer의 row estimate를 얼마나 다르게 만들까요?

실행 엔진: MySQL 8.4.10
누가 실행하나요?

하나의 Session이 같은 SELECT를 histogram 없음, fresh histogram, stale histogram 세 statistics state에서 실행합니다.

무엇을 고정하나요?

동일한 skewed column 분포, predicate, 실제 반환 rows와 statement 결과를 유지합니다.

실행 SQL
SELECT id, customer_id, sales_channel, ordered_at, total_cents
FROM order_events
WHERE sales_channel = 'PARTNER'
ORDER BY ordered_at DESC, id DESC
LIMIT 100;
무엇이 달라지나요?

column distribution에 대한 statistics와 plan의 estimated rows 및 estimate error가 달라집니다.

무엇이 그대로인가요?

실행한 SQL, 실제로 통과한 rows, 반환 결과는 statistics variant 사이에서 그대로입니다.

먼저 예측해 보세요

세 statistics state를 비교할 때 어떤 값을 먼저 봐야 할까요?

세 statistics state를 비교할 때 어떤 값을 먼저 봐야 할까요?

증거 미션

Stale Histogram variant의 estimate error 단계를 열어 histogram이 있어도 freshness가 어긋나면 예측이 어떻게 벌어지는지 확인하세요.

어디를 보나요?
Cardinality lens에서 estimated rows와 actual rows를 같은 Filter operator에서 나란히 읽습니다.
이동할 화면
Stale Histogram · estimate error
무엇이 보여야 하나요?
확인할 관찰

stale histogram이 기억한 PARTNER mass 0.25가 filtered 25.00%로 이어져 32,729행을 예상하지만 actual rows는 128행입니다. histogram은 존재하고 selected key는 null, access type은 ALL로 유지됩니다.

근거 경계
Captured
stale variant의 estimated 32,729와 actual 128 rows
Captured
mutation 전후 동일한 raw histogram bucket과 timestamp
Checkpoint · evidence로 설명하기estimated rows와 actual rows가 서로 다른 이유를 어떻게 구분해야 하나요?답과 근거 확인

estimated rows는 실행 전 statistics 기반 예측이고 actual rows는 captured execution 관측입니다. 같은 operator에서 나란히 비교하되 하나를 다른 하나처럼 표시하면 안 됩니다.

근거 경계
Captured
variant별 estimated rows와 actual rows
이번 Lab의 핵심

statistics는 결과를 바꾸지 않습니다. freshness까지 맞을 때 optimizer의 예상과 실제 row flow 사이 오차를 줄이는 데 도움이 됩니다.

다음 연결

다음 Lab에서는 optimizer가 선택할 수 있는 join algorithm이 outer/inner 또는 build/probe row flow를 어떻게 구성하는지 비교합니다.

용어 확인
cardinality estimate처음 다루는 Lab 03
optimizer가 statistics를 바탕으로 각 operator를 통과할 row 수를 실행 전에 예측한 값입니다.
histogram처음 다루는 Lab 03
column 값의 분포를 bucket으로 요약해 skew가 있는 predicate의 selectivity 추정을 보완하는 statistics입니다.

01 · SOURCE

SQL

1 active fragmentMySQLLIMIT 100
SELECT id, customer_id, sales_channel, ordered_at, total_cents
FROM order_events
WHERE sales_channel = 'PARTNER'
ORDER BY ordered_at DESC, id DESC
LIMIT 100;
02 · FLOW

Native Plan

01 / 12
01/ 12