Files
progcode/web/public/assets/editorial/2019/sql-indexes-plan-reading-2019.svg
huncode bbedf1ae87
Build and deploy / deploy (push) Successful in 14s
revise July 2019 SQL articles
2026-07-31 10:37:50 +03:00

50 lines
3.6 KiB
XML

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 760 650" role="img" aria-labelledby="title desc">
<title id="title">Как читать EXPLAIN ANALYZE от результата к первому расхождению</title>
<desc id="desc">Вертикальное дерево плана показывает Result, Filter и Index Scan. На каждом уровне сравниваются оценка строк, фактические строки, loops и buffers; расследование начинается с первого расхождения снизу.</desc>
<defs>
<style>
.bg { fill: #f8fafc; }
.node { fill: #ffffff; stroke: #94a3b8; stroke-width: 2; }
.scan { fill: #ecfdf5; stroke: #059669; stroke-width: 2; }
.warn { fill: #fff7ed; stroke: #ea580c; stroke-width: 2; }
.note { fill: #eff6ff; stroke: #2563eb; stroke-width: 2; }
.title { font: 700 24px -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; fill: #0f172a; }
.label { font: 700 18px -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; fill: #0f172a; }
.text { font: 15px -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; fill: #334155; }
.mono { font: 600 14px ui-monospace, SFMono-Regular, Menlo, monospace; fill: #0f172a; }
.arrow { stroke: #64748b; stroke-width: 3; fill: none; marker-end: url(#tip); }
.dash { stroke: #ea580c; stroke-width: 3; stroke-dasharray: 7 6; fill: none; marker-end: url(#tipOrange); }
</style>
<marker id="tip" markerWidth="10" markerHeight="10" refX="8" refY="3" orient="auto" markerUnits="strokeWidth">
<path d="M0,0 L0,6 L9,3 z" fill="#64748b" />
</marker>
<marker id="tipOrange" markerWidth="10" markerHeight="10" refX="8" refY="3" orient="auto" markerUnits="strokeWidth">
<path d="M0,0 L0,6 L9,3 z" fill="#ea580c" />
</marker>
</defs>
<rect class="bg" width="760" height="650" rx="28" />
<text class="title" x="42" y="52">План — поток данных, не список красивых узлов</text>
<rect class="node" x="150" y="86" width="360" height="100" rx="14" />
<text class="label" x="178" y="122">Aggregate / Result</text>
<text class="mono" x="178" y="152">rows=1 · actual rows=1 · loops=1</text>
<path class="arrow" d="M330 188 L330 244" />
<rect class="warn" x="150" y="254" width="360" height="116" rx="14" />
<text class="label" x="178" y="291">Filter</text>
<text class="mono" x="178" y="321">rows=100 · actual rows=100 000</text>
<text class="text" x="178" y="347">первое заметное расхождение: ищем причину</text>
<path class="arrow" d="M330 372 L330 428" />
<rect class="scan" x="150" y="438" width="360" height="116" rx="14" />
<text class="label" x="178" y="475">Index Scan</text>
<text class="mono" x="178" y="505">Index Cond: state = 'ready'</text>
<text class="mono" x="178" y="530">Buffers: shared hit/read · loops=1</text>
<rect class="note" x="548" y="235" width="174" height="164" rx="14" />
<text class="label" x="568" y="271">Проверить</text>
<text class="text" x="568" y="302">1. rows vs actual</text>
<text class="text" x="568" y="330">2. loops</text>
<text class="text" x="568" y="358">3. Index Cond</text>
<text class="text" x="568" y="386">4. Buffers</text>
<path class="dash" d="M545 318 L515 318" />
<rect class="node" x="76" y="580" width="608" height="42" rx="12" />
<text class="text" x="106" y="607">Не лечим верхний узел: начинаем с первого места, где оценка потеряла связь с фактом.</text>
</svg>