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

51 lines
3.8 KiB
XML

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 760 650" role="img" aria-labelledby="title desc">
<title id="title">Форма условия должна соответствовать индексному ключу</title>
<desc id="desc">Индекс хранит created_at. Предикат created_at::date создаёт выражение и не совпадает с ключом напрямую, а полуоткрытый диапазон сравнивает исходный created_at и может стать кандидатом для B-tree после проверки плана и семантики времени.</desc>
<defs>
<style>
.bg { fill: #f8fafc; }
.key { fill: #e0f2fe; stroke: #0284c7; stroke-width: 2; }
.bad { fill: #fef2f2; stroke: #dc2626; stroke-width: 2; }
.good { fill: #ecfdf5; stroke: #059669; stroke-width: 2; }
.note { fill: #fffbeb; stroke: #d97706; 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); }
.badline { stroke: #dc2626; stroke-width: 4; }
</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>
</defs>
<rect class="bg" width="760" height="650" rx="28" />
<text class="title" x="42" y="52">Индекс хранит ключ, а не намерение запроса</text>
<rect class="key" x="175" y="84" width="410" height="82" rx="14" />
<text class="label" x="278" y="119">B-tree: (created_at)</text>
<text class="text" x="246" y="146">ключ — исходный timestamp без cast</text>
<path class="arrow" d="M278 168 L184 230" />
<path class="arrow" d="M482 168 L576 230" />
<rect class="bad" x="38" y="240" width="306" height="182" rx="14" />
<text class="label" x="62" y="277">Выражение в WHERE</text>
<text class="mono" x="62" y="311">created_at::date</text>
<text class="mono" x="62" y="337">= DATE '2019-07-10'</text>
<text class="text" x="62" y="373">ключ и выражение разные</text>
<text class="text" x="62" y="399">проверяем range или</text>
<text class="text" x="62" y="420">обоснованный expression index</text>
<line class="badline" x1="78" y1="256" x2="304" y2="406" />
<rect class="good" x="416" y="240" width="306" height="182" rx="14" />
<text class="label" x="440" y="277">Полуоткрытый range</text>
<text class="mono" x="440" y="311">created_at &gt;= day</text>
<text class="mono" x="440" y="337">AND created_at &lt; day + 1</text>
<text class="text" x="440" y="373">исходный ключ сохранён</text>
<text class="text" x="440" y="399">кандидат для B-tree:</text>
<text class="text" x="440" y="420">подтверждаем планом</text>
<path class="arrow" d="M190 424 L285 486" />
<path class="arrow" d="M570 424 L475 486" />
<rect class="note" x="116" y="496" width="528" height="104" rx="14" />
<text class="label" x="148" y="532">Сначала смысл времени, затем EXPLAIN ANALYZE</text>
<text class="text" x="148" y="561">Проверить timezone, rows, Index Cond, Filter и Buffers.</text>
<text class="text" x="148" y="584">Скорость не оправдывает неверную календарную границу.</text>
</svg>