실행 계획은 SQL을 처리하기 위해 옵티마이저가 고른 연산의 트리입니다. 같은 SQL도 데이터 분포, 통계, 인덱스에 따라 순차 스캔이나 인덱스 스캔을 선택할 수 있습니다.
데모는 읽는 행이 많아지는 경로와 인덱스로 후보를 좁히는 경로를 비교합니다. 예상 비용만 보지 말고 실제 실행 시간과 읽은 행·버퍼를 함께 확인해야 합니다.
언제 쓰나
느린 SQL의 병목이 스캔·조인·정렬 중 어디인지 확인할 때 EXPLAIN ANALYZE를 봅니다.
DB가 테이블을 읽고 조인·정렬하는 실제 경로를 보여줍니다.
<div class="demo"><div class="head"><b>EXPLAIN</b><span>WHERE id = 42</span></div><div class="stage plans"><div class="route"><strong>Seq Scan</strong><div class="track" id="wide"></div><small>all rows</small></div><div class="route"><strong>Index Scan</strong><div class="track" id="narrow"></div><small>candidate rows</small></div></div><div class="foot"><span id="planstep">reading rows</span><span>same SQL</span></div></div>*{box-sizing:border-box}.demo{width:min(96vw,820px);height:min(94vh,350px);padding:clamp(8px,2vmin,18px);border:1px solid var(--line);border-radius:14px;background:var(--surface);color:var(--fg);display:flex;flex-direction:column;gap:clamp(5px,1.5vmin,12px);font:600 clamp(12px,3.5vmin,15px)/1.25 var(--font-sans),sans-serif;overflow:hidden}.head,.foot,.row{display:flex;justify-content:space-between;align-items:center;gap:8px}.head b{color:var(--accent)}.head span,.foot,.muted{color:var(--muted)}.stage{flex:1;min-height:0;display:flex;align-items:center;justify-content:center;gap:8px}.cell,.pill{border:1px solid var(--line);border-radius:8px;background:var(--bg);padding:clamp(4px,1.2vmin,9px);text-align:center}.pill{border-radius:999px}.on{border-color:var(--accent)!important;background:color-mix(in srgb,var(--accent) 17%,var(--surface))!important;color:var(--fg)!important}.bad{border-color:#e16a5d!important;background:color-mix(in srgb,#e16a5d 18%,var(--surface))!important}.foot{font-size:clamp(12px,3vmin,14px)}.plans{flex-direction:column;align-items:stretch;justify-content:center}.route{display:grid;grid-template-columns:85px 1fr 95px;align-items:center;gap:7px}.route strong{white-space:nowrap;font-size:12px}.route small{font-size:12px;color:var(--muted)}.track{height:clamp(15px,4vmin,24px);border-radius:5px;background:var(--bg);border:1px solid var(--line);overflow:hidden}.track:before{content:'';display:block;height:100%;width:0;background:var(--accent);transition:width .5s}.track.active:before{width:var(--fill)}#wide{--fill:95%}#narrow{--fill:18%}@media(max-width:400px){.route{grid-template-columns:75px 1fr}.route small{display:none}}let n=0;function tick(){document.querySelectorAll('.track').forEach((e,i)=>e.classList.toggle('active',i===n));document.getElementById('planstep').textContent=n?'index narrows candidates':'scan reads every row';n=1-n}tick();const t=setInterval(tick,1200);document.querySelector('.demo').onclick=()=>{clearInterval(t);tick()}실행 계획은 SQL을 처리하기 위해 옵티마이저가 고른 연산의 트리입니다. 같은 SQL도 데이터 분포, 통계, 인덱스에 따라 순차 스캔이나 인덱스 스캔을 선택할 수 있습니다.
데모는 읽는 행이 많아지는 경로와 인덱스로 후보를 좁히는 경로를 비교합니다. 예상 비용만 보지 말고 실제 실행 시간과 읽은 행·버퍼를 함께 확인해야 합니다.
느린 SQL의 병목이 스캔·조인·정렬 중 어디인지 확인할 때 EXPLAIN ANALYZE를 봅니다.