51 lines
3.8 KiB
XML
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 >= day</text>
|
|
<text class="mono" x="440" y="337">AND created_at < 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>
|