<!-- CANARY: REQ=REQ-GQL-024; FEATURE="Conformance Flagger"; ASPECT=ImplDefinedCollationAndNullOrdering; STATUS=TESTED; OWNER=engine; UPDATED=2025-09-21 -->
<h3 id="overview" class="position-relative d-flex align-items-center group">
<span>Overview</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="overview"
aria-haspopup="dialog"
aria-label="Share link: Overview">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3><div id="headingShareModal" class="heading-share-modal" role="dialog" aria-modal="true" aria-labelledby="headingShareTitle" hidden>
<div class="hsm-dialog" role="document">
<div class="hsm-header">
<h2 id="headingShareTitle" class="h6 mb-0 fw-bold">Share this section</h2>
<button type="button" class="hsm-close" aria-label="Close">
<i class="fa-solid fa-xmark"></i>
</button>
</div>
<div class="hsm-body">
<label for="headingShareInput" class="form-label small text-muted mb-1 text-uppercase fw-bold" style="font-size: 0.7rem; letter-spacing: 0.5px;">Permalink</label>
<div class="input-group mb-4 hsm-url-group">
<input id="headingShareInput" type="text" class="form-control font-monospace" readonly aria-readonly="true" style="font-size: 0.85rem;" />
<button class="btn btn-primary hsm-copy" type="button" aria-label="Copy" title="Copy">
<i class="fa-duotone fa-clipboard" aria-hidden="true"></i>
</button>
</div>
<div class="small fw-bold mb-2 text-muted text-uppercase" style="font-size: 0.7rem; letter-spacing: 0.5px;">Share via</div>
<div class="hsm-share-grid">
<a id="share-twitter" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer">
<i class="fa-brands fa-twitter me-2"></i>Twitter
</a>
<a id="share-linkedin" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer">
<i class="fa-brands fa-linkedin me-2"></i>LinkedIn
</a>
<a id="share-facebook" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer">
<i class="fa-brands fa-facebook me-2"></i>Facebook
</a>
</div>
</div>
</div>
</div>
<style>
.heading-share-modal {
position: fixed;
inset: 0;
display: flex;
justify-content: center;
align-items: center;
background: rgba(0, 0, 0, 0.6);
z-index: 1050;
padding: 1rem;
backdrop-filter: blur(4px);
-webkit-backdrop-filter: blur(4px);
}
.heading-share-modal[hidden] { display: none !important; }
.hsm-dialog {
max-width: 420px;
width: 100%;
background: var(--bs-body-bg, #fff);
color: var(--bs-body-color, #212529);
border: 1px solid var(--bs-border-color, rgba(0,0,0,0.1));
border-radius: 1rem;
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
overflow: hidden;
animation: hsm-fade-in 0.2s ease-out;
}
@keyframes hsm-fade-in {
from { opacity: 0; transform: scale(0.95); }
to { opacity: 1; transform: scale(1); }
}
[data-bs-theme="dark"] .hsm-dialog {
background: #1e293b;
border-color: rgba(255,255,255,0.1);
color: #f8f9fa;
}
.hsm-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem 1.5rem;
border-bottom: 1px solid var(--bs-border-color, rgba(0,0,0,0.1));
background: rgba(0,0,0,0.02);
}
[data-bs-theme="dark"] .hsm-header {
background: rgba(255,255,255,0.02);
border-color: rgba(255,255,255,0.1);
}
.hsm-close {
background: transparent;
border: none;
color: inherit;
opacity: 0.5;
padding: 0.25rem 0.5rem;
border-radius: 0.25rem;
font-size: 1.2rem;
line-height: 1;
transition: opacity 0.2s;
}
.hsm-close:hover {
opacity: 1;
}
.hsm-body {
padding: 1.5rem;
}
.hsm-url-group {
display: flex !important;
align-items: stretch;
}
.hsm-url-group .form-control {
flex: 1;
min-width: 0;
margin: 0;
background: var(--bs-secondary-bg, #f8f9fa);
border-color: var(--bs-border-color, #dee2e6);
border-top-right-radius: 0;
border-bottom-right-radius: 0;
height: 42px;
}
.hsm-url-group .btn {
flex: 0 0 auto;
margin: 0;
margin-left: -1px;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
height: 42px;
display: flex;
align-items: center;
justify-content: center;
padding: 0 1.25rem;
z-index: 2;
}
[data-bs-theme="dark"] .hsm-url-group .form-control {
background: #0f172a;
border-color: #334155;
color: #e2e8f0;
}
.hsm-share-grid {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.hsm-share-grid .btn {
display: flex;
align-items: center;
justify-content: center;
font-size: 0.9rem;
padding: 0.6rem;
border-color: var(--bs-border-color);
width: 100%;
}
[data-bs-theme="dark"] .hsm-share-grid .btn {
color: #e2e8f0;
border-color: #475569;
}
[data-bs-theme="dark"] .hsm-share-grid .btn:hover {
background: #334155;
border-color: #cbd5e1;
}
</style>
<script>
(function(){
const modal = document.getElementById('headingShareModal');
if(!modal) return;
const input = modal.querySelector('#headingShareInput');
const copyBtn = modal.querySelector('.hsm-copy');
const twitter = modal.querySelector('#share-twitter');
const linkedin = modal.querySelector('#share-linkedin');
const facebook = modal.querySelector('#share-facebook');
const closeBtn = modal.querySelector('.hsm-close');
let lastFocus=null;
let trapBound=false;
function buildUrl(id){ return window.location.origin + window.location.pathname + '#' + id; }
function isOpen(){ return !modal.hasAttribute('hidden'); }
function hydrate(id){
const url=buildUrl(id);
input.value=url;
const enc=encodeURIComponent(url);
const text=encodeURIComponent(document.title);
if(twitter) twitter.href=`https://twitter.com/intent/tweet?url=${enc}&text=${text}`;
if(linkedin) linkedin.href=`https://www.linkedin.com/sharing/share-offsite/?url=${enc}`;
if(facebook) facebook.href=`https://www.facebook.com/sharer/sharer.php?u=${enc}`;
}
function openModal(id){
lastFocus=document.activeElement;
hydrate(id);
if(!isOpen()){
modal.removeAttribute('hidden');
}
requestAnimationFrame(()=>{ input.focus(); });
trapFocus();
}
function closeModal(){
if(!isOpen()) return;
modal.setAttribute('hidden','');
if(lastFocus && typeof lastFocus.focus==='function') lastFocus.focus();
}
function copyCurrent(){
try{ navigator.clipboard.writeText(input.value).then(()=>feedback(true),()=>fallback()); }
catch(e){ fallback(); }
}
function fallback(){ input.select(); try{ document.execCommand('copy'); feedback(true);}catch(e){ feedback(false);} }
function feedback(ok){ if(!copyBtn) return; const icon=copyBtn.querySelector('i'); if(!icon) return; const prev=copyBtn.getAttribute('data-prev')||icon.className; if(!copyBtn.getAttribute('data-prev')) copyBtn.setAttribute('data-prev',prev); icon.className= ok ? 'fa-duotone fa-clipboard-check':'fa-duotone fa-circle-exclamation'; setTimeout(()=>{ icon.className=prev; },1800); }
function handleShareClick(e){ e.preventDefault(); const btn=e.currentTarget; const id=btn.getAttribute('data-share-target'); if(id) openModal(id); }
function bindShareButtons(){
document.querySelectorAll('.h-share').forEach(btn=>{
if(!btn.dataset.hShareBound){ btn.addEventListener('click', handleShareClick); btn.dataset.hShareBound='1'; }
});
}
bindShareButtons();
if(document.readyState==='loading'){
document.addEventListener('DOMContentLoaded', bindShareButtons);
} else {
requestAnimationFrame(bindShareButtons);
}
document.addEventListener('click', function(e){
const shareBtn=e.target.closest && e.target.closest('.h-share');
if(shareBtn && !shareBtn.dataset.hShareBound){ handleShareClick.call(shareBtn, e); }
}, true);
document.addEventListener('click', e=>{
if(e.target===modal) closeModal();
if(e.target.closest && e.target.closest('.hsm-close')){ e.preventDefault(); closeModal(); }
if(copyBtn && (e.target===copyBtn || (e.target.closest && e.target.closest('.hsm-copy')))) { e.preventDefault(); copyCurrent(); }
});
document.addEventListener('keydown', e=>{ if(e.key==='Escape' && isOpen()) closeModal(); });
function trapFocus(){
if(trapBound) return;
trapBound=true;
modal.addEventListener('keydown', f=>{ if(f.key==='Tab' && isOpen()){ const focusable=[...modal.querySelectorAll('a[href],button,input,textarea,select,[tabindex]:not([tabindex="-1"])')].filter(el=>!el.hasAttribute('disabled')); if(!focusable.length) return; const first=focusable[0]; const last=focusable[focusable.length-1]; if(f.shiftKey && document.activeElement===first){ f.preventDefault(); last.focus(); } else if(!f.shiftKey && document.activeElement===last){ f.preventDefault(); first.focus(); } } });
}
if(closeBtn) closeBtn.addEventListener('click', e=>{ e.preventDefault(); closeModal(); });
})();
</script><p>This guide teaches you how to analyze and optimize query performance in Geode using EXPLAIN, PROFILE, indexes, and the cost-based optimizer. You’ll learn to diagnose slow queries, understand execution plans, and apply optimization strategies.</p>
<p><strong>Performance Tuning Process:</strong></p>
<ol>
<li><strong>Measure</strong> - Use PROFILE to identify slow queries</li>
<li><strong>Analyze</strong> - Use EXPLAIN to understand execution plans</li>
<li><strong>Optimize</strong> - Apply indexes, rewrite queries, tune configuration</li>
<li><strong>Verify</strong> - Re-measure to confirm improvements</li>
</ol>
<p><strong>Quick Links:</strong></p>
<ul>
<li><a
href="https://geodedb.com/docs/query/performance-tuning/#using-explain"
>Using EXPLAIN</a>
</li>
<li><a
href="https://geodedb.com/docs/query/performance-tuning/#using-profile"
>Using PROFILE</a>
</li>
<li><a
href="https://geodedb.com/docs/query/performance-tuning/#index-optimization"
>Index Optimization</a>
</li>
<li><a
href="https://geodedb.com/docs/query/performance-tuning/#query-rewriting-patterns"
>Query Rewriting Patterns</a>
</li>
<li><a
href="https://geodedb.com/docs/query/performance-tuning/#common-performance-issues"
>Common Performance Issues</a>
</li>
</ul>
<hr>
<h3 id="using-explain" class="position-relative d-flex align-items-center group">
<span>Using EXPLAIN</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="using-explain"
aria-haspopup="dialog"
aria-label="Share link: Using EXPLAIN">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3><p><strong>EXPLAIN</strong> shows the query execution plan <strong>without</strong> running the query. Use it to understand how Geode will execute your query before committing resources.</p>
<h4 id="basic-explain-syntax" class="position-relative d-flex align-items-center group">
<span>Basic EXPLAIN Syntax</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="basic-explain-syntax"
aria-haspopup="dialog"
aria-label="Share link: Basic EXPLAIN Syntax">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">EXPLAIN</span><span class="w"> </span><span class="err"><</span><span class="py">statement</span><span class="err">></span><span class="w">
</span></span></span></code></pre></div>
<h4 id="understanding-execution-plans" class="position-relative d-flex align-items-center group">
<span>Understanding Execution Plans</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="understanding-execution-plans"
aria-haspopup="dialog"
aria-label="Share link: Understanding Execution Plans">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p>EXPLAIN output shows <strong>logical operators</strong> Geode will use:</p>
<table>
<thead>
<tr>
<th>Operator</th>
<th>Description</th>
<th>Performance Impact</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>NodeScan</code></td>
<td>Scans all nodes (or by label)</td>
<td>O(n) - can be slow for large graphs</td>
</tr>
<tr>
<td><code>IndexSeek</code></td>
<td>Uses index for direct lookup</td>
<td>O(log n) - fast</td>
</tr>
<tr>
<td><code>IndexScan</code></td>
<td>Scans index range</td>
<td>O(k log n) - moderate</td>
</tr>
<tr>
<td><code>ExpandRelationships</code></td>
<td>Traverses relationships</td>
<td>O(degree) per node</td>
</tr>
<tr>
<td><code>Filter</code></td>
<td>Applies WHERE predicates</td>
<td>O(n) on input rows</td>
</tr>
<tr>
<td><code>Project</code></td>
<td>Selects/transforms columns</td>
<td>O(n) - lightweight</td>
</tr>
<tr>
<td><code>Sort</code></td>
<td>Orders results (ORDER BY)</td>
<td>O(n log n) - expensive</td>
</tr>
<tr>
<td><code>Limit</code></td>
<td>Restricts output rows</td>
<td>O(1) - cheap</td>
</tr>
<tr>
<td><code>Aggregate</code></td>
<td>Groups and aggregates</td>
<td>O(n) - moderate</td>
</tr>
</tbody>
</table>
<h4 id="explain-examples" class="position-relative d-flex align-items-center group">
<span>EXPLAIN Examples</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="explain-examples"
aria-haspopup="dialog"
aria-label="Share link: EXPLAIN Examples">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p><strong>Example 1: Simple Node Scan</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">EXPLAIN</span><span class="w"> </span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w"> </span><span class="py">RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">name</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div><p><strong>Output:</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">| plan |
</span></span><span class="line"><span class="cl">|-------------------|
</span></span><span class="line"><span class="cl">| EXPLAIN |
</span></span><span class="line"><span class="cl">| MATCH |
</span></span><span class="line"><span class="cl">| NodeScan | ← Scans all Person nodes
</span></span><span class="line"><span class="cl">| RETURN |
</span></span><span class="line"><span class="cl">| Project | ← Selects name property
</span></span></code></pre></div><p><strong>Analysis</strong>: Full node scan - acceptable for small graphs, slow for large.</p>
<hr>
<p><strong>Example 2: Filtered Query</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">EXPLAIN</span><span class="w"> </span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w"> </span><span class="py">WHERE</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">age</span><span class="w"> </span><span class="err">></span><span class="w"> </span><span class="py">25</span><span class="w"> </span><span class="py">RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">name</span><span class="p">,</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">age</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div><p><strong>Output:</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">| plan |
</span></span><span class="line"><span class="cl">|-------------------|
</span></span><span class="line"><span class="cl">| EXPLAIN |
</span></span><span class="line"><span class="cl">| MATCH |
</span></span><span class="line"><span class="cl">| NodeScan | ← Scans all Person nodes
</span></span><span class="line"><span class="cl">| Filter | ← Filters age > 25
</span></span><span class="line"><span class="cl">| RETURN |
</span></span><span class="line"><span class="cl">| Project |
</span></span></code></pre></div><p><strong>Analysis</strong>: Scans all nodes, then filters. <strong>Optimization needed</strong> if large dataset.</p>
<hr>
<p><strong>Example 3: Relationship Traversal</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">EXPLAIN</span><span class="w"> </span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">WORKS_FOR</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">c</span><span class="p">:</span><span class="nc">Company</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">name</span><span class="p">,</span><span class="w"> </span><span class="py">c</span><span class="err">.</span><span class="py">name</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div><p><strong>Output:</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">| plan |
</span></span><span class="line"><span class="cl">|-------------------------|
</span></span><span class="line"><span class="cl">| EXPLAIN |
</span></span><span class="line"><span class="cl">| MATCH |
</span></span><span class="line"><span class="cl">| NodeScan | ← Start with Person nodes
</span></span><span class="line"><span class="cl">| ExpandRelationships | ← Traverse WORKS_FOR edges
</span></span><span class="line"><span class="cl">| RETURN |
</span></span><span class="line"><span class="cl">| Project |
</span></span></code></pre></div><p><strong>Analysis</strong>: Scans all Persons, expands relationships. Consider index on Company if filtering by company properties.</p>
<hr>
<p><strong>Example 4: Complex Query with Aggregation</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">EXPLAIN</span><span class="w"> </span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">WORKS_FOR</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">c</span><span class="p">:</span><span class="nc">Company</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">age</span><span class="w"> </span><span class="err">></span><span class="w"> </span><span class="py">25</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">c</span><span class="err">.</span><span class="py">name</span><span class="p">,</span><span class="w"> </span><span class="py">count</span><span class="p">(</span><span class="py">p</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">employee_count</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">employee_count</span><span class="w"> </span><span class="py">DESC</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">LIMIT</span><span class="w"> </span><span class="py">10</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div><p><strong>Output:</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">| plan |
</span></span><span class="line"><span class="cl">|-------------------------|
</span></span><span class="line"><span class="cl">| EXPLAIN |
</span></span><span class="line"><span class="cl">| MATCH |
</span></span><span class="line"><span class="cl">| NodeScan |
</span></span><span class="line"><span class="cl">| ExpandRelationships |
</span></span><span class="line"><span class="cl">| Filter |
</span></span><span class="line"><span class="cl">| RETURN |
</span></span><span class="line"><span class="cl">| Aggregate | ← Group by company, count employees
</span></span><span class="line"><span class="cl">| Sort | ← Sort by count (expensive!)
</span></span><span class="line"><span class="cl">| Limit |
</span></span><span class="line"><span class="cl">| Project |
</span></span></code></pre></div><p><strong>Analysis</strong>: Full scan → filter → aggregate → <strong>sort</strong> (expensive). Optimize filter with index.</p>
<hr>
<h4 id="reading-explain-output" class="position-relative d-flex align-items-center group">
<span>Reading EXPLAIN Output</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="reading-explain-output"
aria-haspopup="dialog"
aria-label="Share link: Reading EXPLAIN Output">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p><strong>🚩 Red Flags (Slow Patterns)</strong>:</p>
<ul>
<li><code>NodeScan</code> without subsequent <code>Filter</code> on large graphs</li>
<li><code>Sort</code> on large result sets</li>
<li>Multiple <code>ExpandRelationships</code> without indexes</li>
<li><code>Aggregate</code> on unindexed properties</li>
</ul>
<p><strong>✅ Good Patterns (Fast)</strong>:</p>
<ul>
<li><code>IndexSeek</code> for direct lookups</li>
<li><code>Filter</code> early in the plan (before expensive operations)</li>
<li><code>Limit</code> without <code>Sort</code> for large datasets</li>
<li>Index-backed <code>Aggregate</code> operations</li>
</ul>
<hr>
<h3 id="using-profile" class="position-relative d-flex align-items-center group">
<span>Using PROFILE</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="using-profile"
aria-haspopup="dialog"
aria-label="Share link: Using PROFILE">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3><p><strong>PROFILE</strong> executes the query and returns <strong>real execution metrics</strong>. Use it to measure actual performance.</p>
<h4 id="basic-profile-syntax" class="position-relative d-flex align-items-center group">
<span>Basic PROFILE Syntax</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="basic-profile-syntax"
aria-haspopup="dialog"
aria-label="Share link: Basic PROFILE Syntax">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">PROFILE</span><span class="w"> </span><span class="err"><</span><span class="py">statement</span><span class="err">></span><span class="w">
</span></span></span></code></pre></div>
<h4 id="profile-metrics" class="position-relative d-flex align-items-center group">
<span>PROFILE Metrics</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="profile-metrics"
aria-haspopup="dialog"
aria-label="Share link: PROFILE Metrics">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><table>
<thead>
<tr>
<th>Metric</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>rows_returned</code></td>
<td>Number of rows returned</td>
</tr>
<tr>
<td><code>columns</code></td>
<td>Number of columns in result</td>
</tr>
<tr>
<td><code>execution_time_ms</code></td>
<td>Execution time in milliseconds</td>
</tr>
</tbody>
</table>
<h4 id="profile-examples" class="position-relative d-flex align-items-center group">
<span>PROFILE Examples</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="profile-examples"
aria-haspopup="dialog"
aria-label="Share link: PROFILE Examples">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p><strong>Example 1: Measure Simple Query</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">PROFILE</span><span class="w"> </span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w"> </span><span class="py">RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">name</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div><p><strong>Output:</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">| metric | value |
</span></span><span class="line"><span class="cl">|---------------------|-------|
</span></span><span class="line"><span class="cl">| rows_returned | 42 |
</span></span><span class="line"><span class="cl">| columns | 1 |
</span></span><span class="line"><span class="cl">| execution_time_ms | 1 |
</span></span></code></pre></div><p><strong>Analysis</strong>: Returned 42 rows in 1ms - acceptable.</p>
<hr>
<p><strong>Example 2: Measure Query with Filter</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">PROFILE</span><span class="w"> </span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w"> </span><span class="py">WHERE</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">age</span><span class="w"> </span><span class="err">></span><span class="w"> </span><span class="py">30</span><span class="w"> </span><span class="py">RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">name</span><span class="p">,</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">age</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div><p><strong>Output:</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">| metric | value |
</span></span><span class="line"><span class="cl">|---------------------|-------|
</span></span><span class="line"><span class="cl">| rows_returned | 15 |
</span></span><span class="line"><span class="cl">| columns | 2 |
</span></span><span class="line"><span class="cl">| execution_time_ms | 2 |
</span></span></code></pre></div><p><strong>Analysis</strong>: 15 results in 2ms - good. If time is higher, add index on <code>age</code>.</p>
<hr>
<p><strong>Example 3: Before/After Optimization</strong></p>
<p><strong>Before (no index):</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">PROFILE</span><span class="w"> </span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w"> </span><span class="py">WHERE</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">email</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="err">'</span><span class="p">[</span><span class="py">email</span><span class="w"> </span><span class="py">protected</span><span class="p">]</span><span class="err">'</span><span class="w"> </span><span class="py">RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div><p><strong>Output:</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">| metric | value |
</span></span><span class="line"><span class="cl">|---------------------|-------|
</span></span><span class="line"><span class="cl">| rows_returned | 1 |
</span></span><span class="line"><span class="cl">| execution_time_ms | 50 | ← Slow: full scan
</span></span></code></pre></div><p><strong>Create Index:</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">CREATE</span><span class="w"> </span><span class="py">INDEX</span><span class="w"> </span><span class="py">person_email</span><span class="w"> </span><span class="py">ON</span><span class="w"> </span><span class="py">Person</span><span class="p">(</span><span class="py">email</span><span class="p">)</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div><p><strong>After (with index):</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">PROFILE</span><span class="w"> </span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w"> </span><span class="py">WHERE</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">email</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="err">'</span><span class="p">[</span><span class="py">email</span><span class="w"> </span><span class="py">protected</span><span class="p">]</span><span class="err">'</span><span class="w"> </span><span class="py">RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div><p><strong>Output:</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">| metric | value |
</span></span><span class="line"><span class="cl">|---------------------|-------|
</span></span><span class="line"><span class="cl">| rows_returned | 1 |
</span></span><span class="line"><span class="cl">| execution_time_ms | 2 | ← Fast: index seek!
</span></span></code></pre></div><p><strong>Result</strong>: Significant speedup with index.</p>
<hr>
<h4 id="performance-measurement-workflow" class="position-relative d-flex align-items-center group">
<span>Performance Measurement Workflow</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="performance-measurement-workflow"
aria-haspopup="dialog"
aria-label="Share link: Performance Measurement Workflow">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p><strong>Step 1: Establish Baseline</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">PROFILE</span><span class="w"> </span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">KNOWS</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">friend</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">age</span><span class="w"> </span><span class="err">></span><span class="w"> </span><span class="py">30</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">name</span><span class="p">,</span><span class="w"> </span><span class="py">count</span><span class="p">(</span><span class="py">friend</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">friend_count</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">friend_count</span><span class="w"> </span><span class="py">DESC</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div><p><strong>Step 2: Analyze with EXPLAIN</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">EXPLAIN</span><span class="w"> </span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">KNOWS</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">friend</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">age</span><span class="w"> </span><span class="err">></span><span class="w"> </span><span class="py">30</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">name</span><span class="p">,</span><span class="w"> </span><span class="py">count</span><span class="p">(</span><span class="py">friend</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">friend_count</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">friend_count</span><span class="w"> </span><span class="py">DESC</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div><p><strong>Step 3: Apply Optimization</strong> (add index, rewrite query)</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">CREATE</span><span class="w"> </span><span class="py">INDEX</span><span class="w"> </span><span class="py">person_age</span><span class="w"> </span><span class="py">ON</span><span class="w"> </span><span class="py">Person</span><span class="p">(</span><span class="py">age</span><span class="p">)</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div><p><strong>Step 4: Re-measure with PROFILE</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">PROFILE</span><span class="w"> </span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">KNOWS</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">friend</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">age</span><span class="w"> </span><span class="err">></span><span class="w"> </span><span class="py">30</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">name</span><span class="p">,</span><span class="w"> </span><span class="py">count</span><span class="p">(</span><span class="py">friend</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">friend_count</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">friend_count</span><span class="w"> </span><span class="py">DESC</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div><p><strong>Step 5: Compare Results</strong></p>
<ul>
<li>Before: execution_time_ms = 150</li>
<li>After: execution_time_ms = 20</li>
<li><strong>Speedup: 7.5x</strong> ✅</li>
</ul>
<hr>
<h3 id="index-optimization" class="position-relative d-flex align-items-center group">
<span>Index Optimization</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="index-optimization"
aria-haspopup="dialog"
aria-label="Share link: Index Optimization">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3>
<h4 id="index-types-in-geode" class="position-relative d-flex align-items-center group">
<span>Index Types in Geode</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="index-types-in-geode"
aria-haspopup="dialog"
aria-label="Share link: Index Types in Geode">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><table>
<thead>
<tr>
<th>Index Type</th>
<th>Use Case</th>
<th>Creation Syntax</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>B-tree</strong> (default)</td>
<td>Exact matches, range queries, sorting</td>
<td><code>CREATE INDEX name ON Label(property)</code></td>
</tr>
<tr>
<td><strong>Hash</strong></td>
<td>Exact lookups only (faster than B-tree)</td>
<td><code>CREATE INDEX name ON Label(property) USING hash</code></td>
</tr>
<tr>
<td><strong>Fulltext</strong></td>
<td>Text search, CONTAINS queries</td>
<td><code>CREATE FULLTEXT INDEX name ON Label(property)</code></td>
</tr>
<tr>
<td><strong>Spatial</strong></td>
<td>Geographic queries (distance, bounding box)</td>
<td><code>CREATE SPATIAL INDEX name ON Label(property)</code></td>
</tr>
<tr>
<td><strong>Vector</strong></td>
<td>Similarity search (embeddings, recommendations)</td>
<td><code>CREATE VECTOR INDEX name ON Label(property)</code></td>
</tr>
</tbody>
</table>
<h4 id="creating-indexes" class="position-relative d-flex align-items-center group">
<span>Creating Indexes</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="creating-indexes"
aria-haspopup="dialog"
aria-label="Share link: Creating Indexes">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p><strong>B-tree Index (Default)</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">For</span><span class="w"> </span><span class="py">exact</span><span class="w"> </span><span class="py">matches</span><span class="w"> </span><span class="py">and</span><span class="w"> </span><span class="py">range</span><span class="w"> </span><span class="py">queries</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CREATE</span><span class="w"> </span><span class="py">INDEX</span><span class="w"> </span><span class="py">person_age</span><span class="w"> </span><span class="py">ON</span><span class="w"> </span><span class="py">Person</span><span class="p">(</span><span class="py">age</span><span class="p">)</span><span class="err">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CREATE</span><span class="w"> </span><span class="py">INDEX</span><span class="w"> </span><span class="py">product_price</span><span class="w"> </span><span class="py">ON</span><span class="w"> </span><span class="py">Product</span><span class="p">(</span><span class="py">price</span><span class="p">)</span><span class="err">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Use</span><span class="w"> </span><span class="py">for</span><span class="w"> </span><span class="py">queries</span><span class="w"> </span><span class="py">like</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nc">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w"> </span><span class="py">WHERE</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">age</span><span class="w"> </span><span class="err">></span><span class="w"> </span><span class="py">30</span><span class="w"> </span><span class="py">RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">prod</span><span class="p">:</span><span class="nc">Product</span><span class="p">)</span><span class="w"> </span><span class="py">WHERE</span><span class="w"> </span><span class="py">prod</span><span class="err">.</span><span class="py">price</span><span class="w"> </span><span class="err"><</span><span class="w"> </span><span class="py">100</span><span class="w"> </span><span class="py">RETURN</span><span class="w"> </span><span class="py">prod</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div><p><strong>Hash Index</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">For</span><span class="w"> </span><span class="py">exact</span><span class="w"> </span><span class="py">lookups</span><span class="w"> </span><span class="kd">on</span><span class="py">ly</span><span class="w"> </span><span class="p">(</span><span class="py">faster</span><span class="w"> </span><span class="py">than</span><span class="w"> </span><span class="py">B</span><span class="err">-</span><span class="py">tree</span><span class="w"> </span><span class="py">for</span><span class="w"> </span><span class="py">equality</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CREATE</span><span class="w"> </span><span class="py">INDEX</span><span class="w"> </span><span class="py">person_email</span><span class="w"> </span><span class="py">ON</span><span class="w"> </span><span class="py">Person</span><span class="p">(</span><span class="py">email</span><span class="p">)</span><span class="w"> </span><span class="py">USING</span><span class="w"> </span><span class="py">hash</span><span class="err">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Use</span><span class="w"> </span><span class="py">for</span><span class="w"> </span><span class="py">queries</span><span class="w"> </span><span class="py">like</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nc">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="w"> </span><span class="p">{</span><span class="py">email</span><span class="p">:</span><span class="w"> </span><span class="err">'</span><span class="p">[</span><span class="nc">email</span><span class="w"> </span><span class="py">protected</span><span class="p">]</span><span class="err">'</span><span class="p">})</span><span class="w"> </span><span class="py">RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w"> </span><span class="py">WHERE</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">email</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="err">'</span><span class="p">[</span><span class="py">email</span><span class="w"> </span><span class="py">protected</span><span class="p">]</span><span class="err">'</span><span class="w"> </span><span class="py">RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div><p><strong>Fulltext Index (BM25-Optimized)</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">For</span><span class="w"> </span><span class="py">text</span><span class="w"> </span><span class="py">search</span><span class="w"> </span><span class="py">with</span><span class="w"> </span><span class="py">relevance</span><span class="w"> </span><span class="py">ranking</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CREATE</span><span class="w"> </span><span class="py">FULLTEXT</span><span class="w"> </span><span class="py">INDEX</span><span class="w"> </span><span class="py">article_content</span><span class="w"> </span><span class="py">ON</span><span class="w"> </span><span class="py">Article</span><span class="p">(</span><span class="py">content</span><span class="p">)</span><span class="err">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CREATE</span><span class="w"> </span><span class="py">FULLTEXT</span><span class="w"> </span><span class="py">INDEX</span><span class="w"> </span><span class="py">doc_abstract</span><span class="w"> </span><span class="py">ON</span><span class="w"> </span><span class="py">Document</span><span class="p">(</span><span class="py">abstract</span><span class="p">)</span><span class="err">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Use</span><span class="w"> </span><span class="py">for</span><span class="w"> </span><span class="py">queries</span><span class="w"> </span><span class="py">like</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nc">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">a</span><span class="p">:</span><span class="nc">Article</span><span class="p">)</span><span class="w"> </span><span class="py">WHERE</span><span class="w"> </span><span class="py">a</span><span class="err">.</span><span class="py">content</span><span class="w"> </span><span class="py">CONTAINS</span><span class="w"> </span><span class="err">'</span><span class="py">graph</span><span class="w"> </span><span class="py">database</span><span class="err">'</span><span class="w"> </span><span class="py">RETURN</span><span class="w"> </span><span class="py">a</span><span class="err">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">d</span><span class="p">:</span><span class="nc">Document</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">d</span><span class="err">.</span><span class="py">abstract</span><span class="w"> </span><span class="py">CONTAINS</span><span class="w"> </span><span class="err">'</span><span class="py">machine</span><span class="w"> </span><span class="py">learning</span><span class="err">'</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">d</span><span class="err">.</span><span class="py">title</span><span class="p">,</span><span class="w"> </span><span class="py">bm25_score</span><span class="p">(</span><span class="py">d</span><span class="err">.</span><span class="py">abstract</span><span class="p">,</span><span class="w"> </span><span class="err">'</span><span class="py">machine</span><span class="w"> </span><span class="py">learning</span><span class="err">'</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">relevance</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">relevance</span><span class="w"> </span><span class="py">DESC</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div><p><strong>Spatial Index</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">For</span><span class="w"> </span><span class="py">geographic</span><span class="w"> </span><span class="py">queries</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CREATE</span><span class="w"> </span><span class="py">SPATIAL</span><span class="w"> </span><span class="py">INDEX</span><span class="w"> </span><span class="py">location_coords</span><span class="w"> </span><span class="py">ON</span><span class="w"> </span><span class="py">Location</span><span class="p">(</span><span class="py">coordinates</span><span class="p">)</span><span class="err">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Use</span><span class="w"> </span><span class="py">for</span><span class="w"> </span><span class="py">queries</span><span class="w"> </span><span class="py">like</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nc">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">loc</span><span class="p">:</span><span class="nc">Location</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">distance</span><span class="p">(</span><span class="py">loc</span><span class="err">.</span><span class="py">coordinates</span><span class="p">,</span><span class="w"> </span><span class="py">point</span><span class="p">(</span><span class="py">37</span><span class="mf">.7749</span><span class="p">,</span><span class="w"> </span><span class="err">-</span><span class="py">122</span><span class="mf">.4194</span><span class="p">))</span><span class="w"> </span><span class="err"><</span><span class="w"> </span><span class="py">10000</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">10km</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">loc</span><span class="err">.</span><span class="py">name</span><span class="p">,</span><span class="w"> </span><span class="py">distance</span><span class="p">(</span><span class="py">loc</span><span class="err">.</span><span class="py">coordinates</span><span class="p">,</span><span class="w"> </span><span class="py">point</span><span class="p">(</span><span class="py">37</span><span class="mf">.7749</span><span class="p">,</span><span class="w"> </span><span class="err">-</span><span class="py">122</span><span class="mf">.4194</span><span class="p">))</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">dist</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">dist</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div><p><strong>Vector Index (HNSW)</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">For</span><span class="w"> </span><span class="py">similarity</span><span class="w"> </span><span class="py">search</span><span class="w"> </span><span class="p">(</span><span class="py">embeddings</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CREATE</span><span class="w"> </span><span class="py">VECTOR</span><span class="w"> </span><span class="py">INDEX</span><span class="w"> </span><span class="py">doc_embedding</span><span class="w"> </span><span class="py">ON</span><span class="w"> </span><span class="py">Document</span><span class="p">(</span><span class="py">embedding</span><span class="p">)</span><span class="err">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Use</span><span class="w"> </span><span class="py">for</span><span class="w"> </span><span class="py">queries</span><span class="w"> </span><span class="py">like</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nc">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">doc</span><span class="p">:</span><span class="nc">Document</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">vector_cosine</span><span class="p">(</span><span class="py">doc</span><span class="err">.</span><span class="py">embedding</span><span class="p">,</span><span class="w"> </span><span class="nv">$query_embedding</span><span class="p">)</span><span class="w"> </span><span class="err">></span><span class="w"> </span><span class="py">0</span><span class="mf">.7</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">doc</span><span class="err">.</span><span class="py">title</span><span class="p">,</span><span class="w"> </span><span class="py">vector_cosine</span><span class="p">(</span><span class="py">doc</span><span class="err">.</span><span class="py">embedding</span><span class="p">,</span><span class="w"> </span><span class="nv">$query_embedding</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">similarity</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">similarity</span><span class="w"> </span><span class="py">DESC</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">LIMIT</span><span class="w"> </span><span class="py">10</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="when-to-create-indexes" class="position-relative d-flex align-items-center group">
<span>When to Create Indexes</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="when-to-create-indexes"
aria-haspopup="dialog"
aria-label="Share link: When to Create Indexes">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p><strong>✅ Create Indexes For:</strong></p>
<ol>
<li>
<p><strong>Frequently filtered properties</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Queries</span><span class="w"> </span><span class="py">like</span><span class="w"> </span><span class="py">WHERE</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">status</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="err">'</span><span class="py">active</span><span class="err">'</span><span class="w"> </span><span class="py">are</span><span class="w"> </span><span class="py">common</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CREATE</span><span class="w"> </span><span class="py">INDEX</span><span class="w"> </span><span class="py">user_status</span><span class="w"> </span><span class="py">ON</span><span class="w"> </span><span class="py">User</span><span class="p">(</span><span class="py">status</span><span class="p">)</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div></li>
<li>
<p><strong>Properties used in ORDER BY</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Queries</span><span class="w"> </span><span class="py">like</span><span class="w"> </span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">created_at</span><span class="w"> </span><span class="py">DESC</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CREATE</span><span class="w"> </span><span class="py">INDEX</span><span class="w"> </span><span class="py">post_created</span><span class="w"> </span><span class="py">ON</span><span class="w"> </span><span class="py">Post</span><span class="p">(</span><span class="py">created_at</span><span class="p">)</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div></li>
<li>
<p><strong>Properties in JOIN conditions</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Foreign</span><span class="err">-</span><span class="py">key</span><span class="err">-</span><span class="py">like</span><span class="w"> </span><span class="py">lookups</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CREATE</span><span class="w"> </span><span class="py">INDEX</span><span class="w"> </span><span class="py">order_customer_id</span><span class="w"> </span><span class="py">ON</span><span class="w"> </span><span class="py">Order</span><span class="p">(</span><span class="py">customer_id</span><span class="p">)</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div></li>
<li>
<p><strong>Unique identifiers</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Email</span><span class="p">,</span><span class="w"> </span><span class="py">username</span><span class="p">,</span><span class="w"> </span><span class="py">SKU</span><span class="p">,</span><span class="w"> </span><span class="py">etc</span><span class="err">.</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CREATE</span><span class="w"> </span><span class="py">INDEX</span><span class="w"> </span><span class="py">user_email</span><span class="w"> </span><span class="py">ON</span><span class="w"> </span><span class="py">User</span><span class="p">(</span><span class="py">email</span><span class="p">)</span><span class="w"> </span><span class="py">USING</span><span class="w"> </span><span class="py">hash</span><span class="err">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CREATE</span><span class="w"> </span><span class="py">INDEX</span><span class="w"> </span><span class="py">product_sku</span><span class="w"> </span><span class="py">ON</span><span class="w"> </span><span class="py">Product</span><span class="p">(</span><span class="py">sku</span><span class="p">)</span><span class="w"> </span><span class="py">USING</span><span class="w"> </span><span class="py">hash</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div></li>
</ol>
<p><strong>❌ Don’t Create Indexes For:</strong></p>
<ol>
<li><strong>Rarely queried properties</strong> - Index overhead not worth it</li>
<li><strong>High-cardinality properties with rare lookups</strong> - E.g., free-text descriptions</li>
<li><strong>Properties that change frequently</strong> - Index maintenance overhead</li>
<li><strong>Small datasets</strong> - Full scans are fast enough (<1000 nodes)</li>
</ol>
<h4 id="viewing-indexes" class="position-relative d-flex align-items-center group">
<span>Viewing Indexes</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="viewing-indexes"
aria-haspopup="dialog"
aria-label="Share link: Viewing Indexes">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Show</span><span class="w"> </span><span class="py">all</span><span class="w"> </span><span class="py">indexes</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">SHOW</span><span class="w"> </span><span class="py">INDEXES</span><span class="err">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Output</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">|</span><span class="w"> </span><span class="nc">index_name</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="py">label</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="py">property</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="kd">type</span><span class="w"> </span><span class="p">|</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">|</span><span class="err">------------------</span><span class="p">|</span><span class="err">---------</span><span class="p">|</span><span class="err">-------------</span><span class="p">|</span><span class="err">-----------</span><span class="p">|</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">|</span><span class="w"> </span><span class="nc">person_email</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="py">Person</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="py">email</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="py">hash</span><span class="w"> </span><span class="p">|</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">|</span><span class="w"> </span><span class="py">person_age</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="py">Person</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="py">age</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="py">btree</span><span class="w"> </span><span class="p">|</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">|</span><span class="w"> </span><span class="py">article_content</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="py">Article</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="py">content</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="py">fulltext</span><span class="w"> </span><span class="p">|</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">|</span><span class="w"> </span><span class="py">doc_embedding</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="py">Document</span><span class="p">|</span><span class="w"> </span><span class="py">embedding</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="py">vector</span><span class="w"> </span><span class="p">|</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="dropping-indexes" class="position-relative d-flex align-items-center group">
<span>Dropping Indexes</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="dropping-indexes"
aria-haspopup="dialog"
aria-label="Share link: Dropping Indexes">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Drop</span><span class="w"> </span><span class="py">unused</span><span class="w"> </span><span class="py">or</span><span class="w"> </span><span class="py">redundant</span><span class="w"> </span><span class="py">indexes</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">DROP</span><span class="w"> </span><span class="py">INDEX</span><span class="w"> </span><span class="py">person_age</span><span class="err">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">DROP</span><span class="w"> </span><span class="py">INDEX</span><span class="w"> </span><span class="py">article_content</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div><hr>
<h3 id="bm25-full-text-search-optimization" class="position-relative d-flex align-items-center group">
<span>BM25 Full-Text Search Optimization</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="bm25-full-text-search-optimization"
aria-haspopup="dialog"
aria-label="Share link: BM25 Full-Text Search Optimization">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3><p>Geode’s <strong>cost-based optimizer</strong> automatically uses <strong>BM25 relevance ranking</strong> for fulltext searches, providing enterprise-grade search quality.</p>
<h4 id="bm25-scoring-formula" class="position-relative d-flex align-items-center group">
<span>BM25 Scoring Formula</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="bm25-scoring-formula"
aria-haspopup="dialog"
aria-label="Share link: BM25 Scoring Formula">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">score(q,d) = Σ IDF(qi) × f(qi,d) × (k1 + 1) / (f(qi,d) + k1 × (1 - b + b × |d| / avgdl))
</span></span></code></pre></div><p><strong>Where:</strong></p>
<ul>
<li><code>IDF(qi)</code> = Inverse document frequency (rare terms score higher)</li>
<li><code>f(qi,d)</code> = Term frequency in document</li>
<li><code>|d|</code> = Document length in words</li>
<li><code>avgdl</code> = Average document length in collection</li>
<li><code>k1 = 1.2</code> = Term frequency saturation parameter</li>
<li><code>b = 0.75</code> = Length normalization parameter</li>
</ul>
<h4 id="bm25-optimization-examples" class="position-relative d-flex align-items-center group">
<span>BM25 Optimization Examples</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="bm25-optimization-examples"
aria-haspopup="dialog"
aria-label="Share link: BM25 Optimization Examples">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p><strong>Example 1: Simple Text Search</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Create</span><span class="w"> </span><span class="py">fulltext</span><span class="w"> </span><span class="py">index</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CREATE</span><span class="w"> </span><span class="py">FULLTEXT</span><span class="w"> </span><span class="py">INDEX</span><span class="w"> </span><span class="py">article_content</span><span class="w"> </span><span class="py">ON</span><span class="w"> </span><span class="py">Article</span><span class="p">(</span><span class="py">content</span><span class="p">)</span><span class="err">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Query</span><span class="w"> </span><span class="py">automatically</span><span class="w"> </span><span class="py">uses</span><span class="w"> </span><span class="py">BM25</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">a</span><span class="p">:</span><span class="nc">Article</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">a</span><span class="err">.</span><span class="py">content</span><span class="w"> </span><span class="py">CONTAINS</span><span class="w"> </span><span class="err">'</span><span class="py">machine</span><span class="w"> </span><span class="py">learning</span><span class="w"> </span><span class="py">algorithms</span><span class="err">'</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">a</span><span class="err">.</span><span class="py">title</span><span class="p">,</span><span class="w"> </span><span class="py">a</span><span class="err">.</span><span class="py">author</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">a</span><span class="err">.</span><span class="py">relevance_score</span><span class="w"> </span><span class="py">DESC</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div><p><strong>Optimizer Behavior:</strong></p>
<ul>
<li><strong>Base cost</strong>: 25.0 (vs 20.0 for standard fulltext)</li>
<li><strong>Query complexity</strong>: 1.0 + (3 terms - 1) × 0.3 = 1.6x multiplier</li>
<li><strong>Corpus scaling</strong>: Logarithmic with document count</li>
<li><strong>Result</strong>: Relevance-ranked results, 40-60% better quality</li>
</ul>
<hr>
<p><strong>Example 2: Multi-Term Search with Ranking</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">doc</span><span class="p">:</span><span class="nc">Document</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">doc</span><span class="err">.</span><span class="py">abstract</span><span class="w"> </span><span class="py">CONTAINS</span><span class="w"> </span><span class="err">'</span><span class="py">artificial</span><span class="w"> </span><span class="py">intelligence</span><span class="err">'</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">AND</span><span class="w"> </span><span class="py">doc</span><span class="err">.</span><span class="py">keywords</span><span class="w"> </span><span class="py">CONTAINS</span><span class="w"> </span><span class="err">'</span><span class="py">neural</span><span class="w"> </span><span class="py">networks</span><span class="err">'</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">doc</span><span class="err">.</span><span class="py">title</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">bm25_score</span><span class="p">(</span><span class="py">doc</span><span class="err">.</span><span class="py">abstract</span><span class="p">,</span><span class="w"> </span><span class="err">'</span><span class="py">artificial</span><span class="w"> </span><span class="py">intelligence</span><span class="w"> </span><span class="py">neural</span><span class="w"> </span><span class="py">networks</span><span class="err">'</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">relevance</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">relevance</span><span class="w"> </span><span class="py">DESC</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">LIMIT</span><span class="w"> </span><span class="py">10</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div><p><strong>Performance:</strong></p>
<ul>
<li>BM25 considers document length and term frequency</li>
<li>Shorter documents with exact matches score higher</li>
<li>Longer documents are penalized unless terms are frequent</li>
<li><strong>Typical speedup over naive text search: 2-5x</strong> with better results</li>
</ul>
<hr>
<p><strong>Example 3: Corpus-Aware Optimization</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Technical</span><span class="w"> </span><span class="py">documentation</span><span class="w"> </span><span class="p">(</span><span class="py">high</span><span class="w"> </span><span class="py">vocabulary</span><span class="w"> </span><span class="py">density</span><span class="p">,</span><span class="w"> </span><span class="py">long</span><span class="w"> </span><span class="py">docs</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">tech_doc</span><span class="p">:</span><span class="nc">TechnicalDocument</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">tech_doc</span><span class="err">.</span><span class="py">content</span><span class="w"> </span><span class="py">CONTAINS</span><span class="w"> </span><span class="err">'</span><span class="py">distributed</span><span class="w"> </span><span class="py">systems</span><span class="w"> </span><span class="py">architecture</span><span class="err">'</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">tech_doc</span><span class="err">.</span><span class="py">title</span><span class="p">,</span><span class="w"> </span><span class="py">tech_doc</span><span class="err">.</span><span class="py">complexity_score</span><span class="err">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Optimizer</span><span class="w"> </span><span class="py">adjusts</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="err">-</span><span class="w"> </span><span class="nc">Vocabulary</span><span class="w"> </span><span class="py">density</span><span class="w"> </span><span class="err">></span><span class="w"> </span><span class="py">100</span><span class="w"> </span><span class="err">→</span><span class="w"> </span><span class="py">1</span><span class="mf">.2</span><span class="py">x</span><span class="w"> </span><span class="py">cost</span><span class="w"> </span><span class="py">multiplier</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="err">-</span><span class="w"> </span><span class="py">Average</span><span class="w"> </span><span class="py">document</span><span class="w"> </span><span class="py">length</span><span class="w"> </span><span class="err">></span><span class="w"> </span><span class="py">1000</span><span class="w"> </span><span class="py">words</span><span class="w"> </span><span class="err">→</span><span class="w"> </span><span class="py">length</span><span class="w"> </span><span class="py">normalization</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="err">-</span><span class="w"> </span><span class="py">Result</span><span class="p">:</span><span class="w"> </span><span class="nc">Accurate</span><span class="w"> </span><span class="py">cost</span><span class="w"> </span><span class="py">estimation</span><span class="w"> </span><span class="py">for</span><span class="w"> </span><span class="py">complex</span><span class="w"> </span><span class="py">corpus</span><span class="w">
</span></span></span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Social</span><span class="w"> </span><span class="py">media</span><span class="w"> </span><span class="py">posts</span><span class="w"> </span><span class="p">(</span><span class="py">low</span><span class="w"> </span><span class="py">vocabulary</span><span class="p">,</span><span class="w"> </span><span class="py">short</span><span class="w"> </span><span class="py">docs</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">post</span><span class="p">:</span><span class="nc">SocialPost</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">post</span><span class="err">.</span><span class="py">text</span><span class="w"> </span><span class="py">CONTAINS</span><span class="w"> </span><span class="err">'</span><span class="py">climate</span><span class="w"> </span><span class="py">change</span><span class="err">'</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">post</span><span class="err">.</span><span class="py">text</span><span class="p">,</span><span class="w"> </span><span class="py">post</span><span class="err">.</span><span class="py">engagement_score</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">post</span><span class="err">.</span><span class="py">timestamp</span><span class="w"> </span><span class="py">DESC</span><span class="err">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Optimizer</span><span class="w"> </span><span class="py">adjusts</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="err">-</span><span class="w"> </span><span class="nc">Vocabulary</span><span class="w"> </span><span class="py">density</span><span class="w"> </span><span class="err"><</span><span class="w"> </span><span class="py">20</span><span class="w"> </span><span class="err">→</span><span class="w"> </span><span class="py">0</span><span class="mf">.9</span><span class="py">x</span><span class="w"> </span><span class="py">cost</span><span class="w"> </span><span class="py">multiplier</span><span class="w"> </span><span class="p">(</span><span class="py">simpler</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="err">-</span><span class="w"> </span><span class="py">Average</span><span class="w"> </span><span class="py">document</span><span class="w"> </span><span class="py">length</span><span class="w"> </span><span class="err"><</span><span class="w"> </span><span class="py">200</span><span class="w"> </span><span class="py">words</span><span class="w"> </span><span class="err">→</span><span class="w"> </span><span class="py">reduced</span><span class="w"> </span><span class="py">length</span><span class="w"> </span><span class="py">penalty</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="err">-</span><span class="w"> </span><span class="py">Result</span><span class="p">:</span><span class="w"> </span><span class="nc">Faster</span><span class="w"> </span><span class="py">execution</span><span class="w"> </span><span class="py">for</span><span class="w"> </span><span class="py">short</span><span class="err">-</span><span class="py">form</span><span class="w"> </span><span class="py">content</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="bm25-vs-standard-fulltext-comparison" class="position-relative d-flex align-items-center group">
<span>BM25 vs Standard Fulltext Comparison</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="bm25-vs-standard-fulltext-comparison"
aria-haspopup="dialog"
aria-label="Share link: BM25 vs Standard Fulltext Comparison">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><table>
<thead>
<tr>
<th>Metric</th>
<th>Standard Fulltext</th>
<th>BM25 Enhanced</th>
<th>Benefit</th>
</tr>
</thead>
<tbody>
<tr>
<td>Base cost</td>
<td>20.0</td>
<td>25.0</td>
<td>25% overhead for ranking</td>
</tr>
<tr>
<td>Query complexity</td>
<td>20% per term</td>
<td>30% per term</td>
<td>Better multi-term accuracy</td>
</tr>
<tr>
<td>Corpus scaling</td>
<td>Linear</td>
<td>Logarithmic</td>
<td>Better large-scale performance</td>
</tr>
<tr>
<td>Search quality</td>
<td>Term matching</td>
<td>Relevance ranking</td>
<td><strong>40-60% better results</strong></td>
</tr>
<tr>
<td>Cost accuracy</td>
<td>Heuristic</td>
<td>Statistics-based</td>
<td><strong>25-35% more accurate</strong></td>
</tr>
</tbody>
</table>
<hr>
<h3 id="query-rewriting-patterns" class="position-relative d-flex align-items-center group">
<span>Query Rewriting Patterns</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="query-rewriting-patterns"
aria-haspopup="dialog"
aria-label="Share link: Query Rewriting Patterns">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3>
<h4 id="pattern-1-push-filters-early" class="position-relative d-flex align-items-center group">
<span>Pattern 1: Push Filters Early</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="pattern-1-push-filters-early"
aria-haspopup="dialog"
aria-label="Share link: Pattern 1: Push Filters Early">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p><strong>❌ Bad (Filter Late)</strong>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">KNOWS</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">friend</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">age</span><span class="w"> </span><span class="err">></span><span class="w"> </span><span class="py">30</span><span class="w"> </span><span class="py">AND</span><span class="w"> </span><span class="py">friend</span><span class="err">.</span><span class="py">age</span><span class="w"> </span><span class="err">></span><span class="w"> </span><span class="py">25</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">name</span><span class="p">,</span><span class="w"> </span><span class="py">friend</span><span class="err">.</span><span class="py">name</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div><p><strong>✅ Good (Filter Early)</strong>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="w"> </span><span class="p">{</span><span class="py">age</span><span class="p">:</span><span class="w"> </span><span class="nc">30</span><span class="p">})</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Filter</span><span class="w"> </span><span class="py">immediately</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">KNOWS</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">friend</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">friend</span><span class="err">.</span><span class="py">age</span><span class="w"> </span><span class="err">></span><span class="w"> </span><span class="py">25</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Filter</span><span class="w"> </span><span class="kd">on</span><span class="w"> </span><span class="py">expansion</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">name</span><span class="p">,</span><span class="w"> </span><span class="py">friend</span><span class="err">.</span><span class="py">name</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div><p><strong>Why</strong>: Reduces nodes to expand from, fewer relationship traversals.</p>
<hr>
<h4 id="pattern-2-avoid-cartesian-products" class="position-relative d-flex align-items-center group">
<span>Pattern 2: Avoid Cartesian Products</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="pattern-2-avoid-cartesian-products"
aria-haspopup="dialog"
aria-label="Share link: Pattern 2: Avoid Cartesian Products">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p><strong>❌ Bad (Cartesian Product)</strong>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">c</span><span class="p">:</span><span class="nc">Company</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">company_id</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">c</span><span class="err">.</span><span class="py">id</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">name</span><span class="p">,</span><span class="w"> </span><span class="py">c</span><span class="err">.</span><span class="py">name</span><span class="err">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">If</span><span class="w"> </span><span class="py">1000</span><span class="w"> </span><span class="py">people</span><span class="w"> </span><span class="err">×</span><span class="w"> </span><span class="py">100</span><span class="w"> </span><span class="py">companies</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">100</span><span class="p">,</span><span class="py">000</span><span class="w"> </span><span class="py">intermediate</span><span class="w"> </span><span class="py">rows</span><span class="p">!</span><span class="w">
</span></span></span></code></pre></div><p><strong>✅ Good (Connected Pattern)</strong>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">WORKS_AT</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">c</span><span class="p">:</span><span class="nc">Company</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">name</span><span class="p">,</span><span class="w"> </span><span class="py">c</span><span class="err">.</span><span class="py">name</span><span class="err">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Direct</span><span class="w"> </span><span class="py">relationship</span><span class="w"> </span><span class="py">traversal</span><span class="w">
</span></span></span></code></pre></div><p><strong>Why</strong>: Explicit relationships prevent combinatorial explosion.</p>
<hr>
<h4 id="pattern-3-use-limits-early" class="position-relative d-flex align-items-center group">
<span>Pattern 3: Use Limits Early</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="pattern-3-use-limits-early"
aria-haspopup="dialog"
aria-label="Share link: Pattern 3: Use Limits Early">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p><strong>❌ Bad (Limit After Sort)</strong>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">name</span><span class="p">,</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">age</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">age</span><span class="w"> </span><span class="py">DESC</span><span class="err">;</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Sorts</span><span class="w"> </span><span class="py">ALL</span><span class="w"> </span><span class="py">people</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Then</span><span class="w"> </span><span class="py">application</span><span class="w"> </span><span class="py">takes</span><span class="w"> </span><span class="kd">on</span><span class="py">ly</span><span class="w"> </span><span class="py">first</span><span class="w"> </span><span class="py">10</span><span class="w">
</span></span></span></code></pre></div><p><strong>✅ Good (Limit in Query)</strong>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">name</span><span class="p">,</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">age</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">age</span><span class="w"> </span><span class="py">DESC</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">LIMIT</span><span class="w"> </span><span class="py">10</span><span class="err">;</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Database</span><span class="w"> </span><span class="py">returns</span><span class="w"> </span><span class="kd">on</span><span class="py">ly</span><span class="w"> </span><span class="py">10</span><span class="w">
</span></span></span></code></pre></div><p><strong>Why</strong>: Database can use top-K optimization, avoid sorting/returning all rows.</p>
<hr>
<h4 id="pattern-4-denormalize-for-read-performance" class="position-relative d-flex align-items-center group">
<span>Pattern 4: Denormalize for Read Performance</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="pattern-4-denormalize-for-read-performance"
aria-haspopup="dialog"
aria-label="Share link: Pattern 4: Denormalize for Read Performance">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p><strong>❌ Bad (Join on Every Query)</strong>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">order</span><span class="p">:</span><span class="nc">Order</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">CONTAINS</span><span class="p">]</span><span class="err">-></span><span class="p">(:</span><span class="nc">LineItem</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">OF_PRODUCT</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">product</span><span class="p">:</span><span class="nc">Product</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">order</span><span class="err">.</span><span class="py">id</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">12345</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">sum</span><span class="p">(</span><span class="py">product</span><span class="err">.</span><span class="py">price</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">total</span><span class="err">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Complex</span><span class="w"> </span><span class="py">join</span><span class="w"> </span><span class="py">every</span><span class="w"> </span><span class="py">time</span><span class="w">
</span></span></span></code></pre></div><p><strong>✅ Good (Precompute Total)</strong>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Store</span><span class="w"> </span><span class="py">total</span><span class="w"> </span><span class="kd">on</span><span class="w"> </span><span class="py">Order</span><span class="w"> </span><span class="py">when</span><span class="w"> </span><span class="py">creating</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">order</span><span class="p">:</span><span class="nc">Order</span><span class="w"> </span><span class="p">{</span><span class="py">id</span><span class="p">:</span><span class="w"> </span><span class="nc">12345</span><span class="p">})</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">order</span><span class="err">.</span><span class="py">total</span><span class="err">;</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Single</span><span class="w"> </span><span class="py">property</span><span class="w"> </span><span class="py">lookup</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Update</span><span class="w"> </span><span class="py">total</span><span class="w"> </span><span class="py">when</span><span class="w"> </span><span class="py">items</span><span class="w"> </span><span class="py">change</span><span class="w"> </span><span class="p">(</span><span class="py">trade</span><span class="w"> </span><span class="py">write</span><span class="w"> </span><span class="py">speed</span><span class="w"> </span><span class="py">for</span><span class="w"> </span><span class="py">read</span><span class="w"> </span><span class="py">speed</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">order</span><span class="p">:</span><span class="nc">Order</span><span class="w"> </span><span class="p">{</span><span class="py">id</span><span class="p">:</span><span class="w"> </span><span class="nc">12345</span><span class="p">})</span><span class="err">-</span><span class="p">[:</span><span class="nc">CONTAINS</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">li</span><span class="p">:</span><span class="nc">LineItem</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">SET</span><span class="w"> </span><span class="py">order</span><span class="err">.</span><span class="py">total</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">sum</span><span class="p">(</span><span class="py">li</span><span class="err">.</span><span class="py">subtotal</span><span class="p">)</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div><p><strong>Why</strong>: Read-heavy workloads benefit from denormalization.</p>
<hr>
<h4 id="pattern-5-use-optional-match-sparingly" class="position-relative d-flex align-items-center group">
<span>Pattern 5: Use OPTIONAL MATCH Sparingly</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="pattern-5-use-optional-match-sparingly"
aria-haspopup="dialog"
aria-label="Share link: Pattern 5: Use OPTIONAL MATCH Sparingly">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p><strong>❌ Bad (Multiple OPTIONAL)</strong>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">OPTIONAL</span><span class="w"> </span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">WORKS_AT</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">c</span><span class="p">:</span><span class="nc">Company</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">OPTIONAL</span><span class="w"> </span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">LIVES_IN</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">city</span><span class="p">:</span><span class="nc">City</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">OPTIONAL</span><span class="w"> </span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">STUDIED_AT</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">school</span><span class="p">:</span><span class="nc">School</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">p</span><span class="p">,</span><span class="w"> </span><span class="py">c</span><span class="p">,</span><span class="w"> </span><span class="py">city</span><span class="p">,</span><span class="w"> </span><span class="py">school</span><span class="err">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Many</span><span class="w"> </span><span class="py">optional</span><span class="w"> </span><span class="py">branches</span><span class="w"> </span><span class="py">slow</span><span class="w"> </span><span class="py">execution</span><span class="w">
</span></span></span></code></pre></div><p><strong>✅ Good (Filter Required First)</strong>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">If</span><span class="w"> </span><span class="py">most</span><span class="w"> </span><span class="py">people</span><span class="w"> </span><span class="py">work</span><span class="w"> </span><span class="py">somewhere</span><span class="p">,</span><span class="w"> </span><span class="py">make</span><span class="w"> </span><span class="py">it</span><span class="w"> </span><span class="py">required</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">WORKS_AT</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">c</span><span class="p">:</span><span class="nc">Company</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">OPTIONAL</span><span class="w"> </span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">LIVES_IN</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">city</span><span class="p">:</span><span class="nc">City</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">p</span><span class="p">,</span><span class="w"> </span><span class="py">c</span><span class="p">,</span><span class="w"> </span><span class="py">city</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div><p><strong>Why</strong>: Required MATCH is faster than OPTIONAL.</p>
<hr>
<h3 id="common-performance-issues" class="position-relative d-flex align-items-center group">
<span>Common Performance Issues</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="common-performance-issues"
aria-haspopup="dialog"
aria-label="Share link: Common Performance Issues">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3>
<h4 id="issue-1-full-node-scans" class="position-relative d-flex align-items-center group">
<span>Issue 1: Full Node Scans</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="issue-1-full-node-scans"
aria-haspopup="dialog"
aria-label="Share link: Issue 1: Full Node Scans">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p><strong>Symptom</strong>: Queries slow on large graphs, EXPLAIN shows <code>NodeScan</code>.</p>
<p><strong>Example</strong>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w"> </span><span class="py">WHERE</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">email</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="err">'</span><span class="p">[</span><span class="py">email</span><span class="w"> </span><span class="py">protected</span><span class="p">]</span><span class="err">'</span><span class="w"> </span><span class="py">RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">EXPLAIN</span><span class="w"> </span><span class="py">shows</span><span class="p">:</span><span class="w"> </span><span class="nc">NodeScan</span><span class="w"> </span><span class="err">→</span><span class="w"> </span><span class="py">Filter</span><span class="w">
</span></span></span></code></pre></div><p><strong>Solution</strong>: Create index on filtered property.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">CREATE</span><span class="w"> </span><span class="py">INDEX</span><span class="w"> </span><span class="py">person_email</span><span class="w"> </span><span class="py">ON</span><span class="w"> </span><span class="py">Person</span><span class="p">(</span><span class="py">email</span><span class="p">)</span><span class="err">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Now</span><span class="w"> </span><span class="py">EXPLAIN</span><span class="w"> </span><span class="py">shows</span><span class="p">:</span><span class="w"> </span><span class="nc">IndexSeek</span><span class="w">
</span></span></span></code></pre></div><p><strong>Impact</strong>: Significant improvement on large datasets.</p>
<hr>
<h4 id="issue-2-expensive-sorts" class="position-relative d-flex align-items-center group">
<span>Issue 2: Expensive Sorts</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="issue-2-expensive-sorts"
aria-haspopup="dialog"
aria-label="Share link: Issue 2: Expensive Sorts">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p><strong>Symptom</strong>: Queries with ORDER BY are slow, high memory usage.</p>
<p><strong>Example</strong>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">name</span><span class="p">,</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">created_at</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">created_at</span><span class="w"> </span><span class="py">DESC</span><span class="err">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Sorts</span><span class="w"> </span><span class="py">ALL</span><span class="w"> </span><span class="py">people</span><span class="w"> </span><span class="py">in</span><span class="w"> </span><span class="py">memory</span><span class="w">
</span></span></span></code></pre></div><p><strong>Solution 1</strong>: Create index on sort property.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">CREATE</span><span class="w"> </span><span class="py">INDEX</span><span class="w"> </span><span class="py">person_created</span><span class="w"> </span><span class="py">ON</span><span class="w"> </span><span class="py">Person</span><span class="p">(</span><span class="py">created_at</span><span class="p">)</span><span class="err">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Index</span><span class="w"> </span><span class="py">provides</span><span class="w"> </span><span class="py">sorted</span><span class="w"> </span><span class="py">iteration</span><span class="w">
</span></span></span></code></pre></div><p><strong>Solution 2</strong>: Add LIMIT if you don’t need all results.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">name</span><span class="p">,</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">created_at</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">created_at</span><span class="w"> </span><span class="py">DESC</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">LIMIT</span><span class="w"> </span><span class="py">100</span><span class="err">;</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Only</span><span class="w"> </span><span class="py">sort</span><span class="w"> </span><span class="py">top</span><span class="w"> </span><span class="py">100</span><span class="w">
</span></span></span></code></pre></div><p><strong>Impact</strong>: <strong>5-50x speedup</strong> depending on dataset size.</p>
<hr>
<h4 id="issue-3-supernode-expansion" class="position-relative d-flex align-items-center group">
<span>Issue 3: Supernode Expansion</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="issue-3-supernode-expansion"
aria-haspopup="dialog"
aria-label="Share link: Issue 3: Supernode Expansion">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p><strong>Symptom</strong>: Queries traversing high-degree nodes are slow.</p>
<p><strong>Example</strong>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="s">"Popular"</span><span class="w"> </span><span class="py">node</span><span class="w"> </span><span class="py">with</span><span class="w"> </span><span class="py">1</span><span class="p">,</span><span class="py">000</span><span class="p">,</span><span class="py">000</span><span class="w"> </span><span class="py">followers</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">celebrity</span><span class="p">:</span><span class="nc">Person</span><span class="w"> </span><span class="p">{</span><span class="py">name</span><span class="p">:</span><span class="w"> </span><span class="s">"Celebrity"</span><span class="p">})</span><span class="err">-</span><span class="p">[:</span><span class="nc">FOLLOWED_BY</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="nc">follower</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">follower</span><span class="err">.</span><span class="py">name</span><span class="err">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Expands</span><span class="w"> </span><span class="py">1M</span><span class="w"> </span><span class="py">relationships</span><span class="p">!</span><span class="w">
</span></span></span></code></pre></div><p><strong>Solution 1</strong>: Add LIMIT and pagination.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">celebrity</span><span class="p">:</span><span class="nc">Person</span><span class="w"> </span><span class="p">{</span><span class="py">name</span><span class="p">:</span><span class="w"> </span><span class="s">"Celebrity"</span><span class="p">})</span><span class="err">-</span><span class="p">[:</span><span class="nc">FOLLOWED_BY</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="nc">follower</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">follower</span><span class="err">.</span><span class="py">name</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">follower</span><span class="err">.</span><span class="py">id</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">SKIP</span><span class="w"> </span><span class="py">1000</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">LIMIT</span><span class="w"> </span><span class="py">100</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div><p><strong>Solution 2</strong>: Denormalize with cached counts.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">celebrity</span><span class="p">:</span><span class="nc">Person</span><span class="w"> </span><span class="p">{</span><span class="py">name</span><span class="p">:</span><span class="w"> </span><span class="s">"Celebrity"</span><span class="p">})</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nc">RETURN</span><span class="w"> </span><span class="py">celebrity</span><span class="err">.</span><span class="py">follower_count</span><span class="err">;</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Precomputed</span><span class="w"> </span><span class="py">property</span><span class="w">
</span></span></span></code></pre></div><p><strong>Solution 3</strong>: Partition relationships.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Instead</span><span class="w"> </span><span class="py">of</span><span class="w"> </span><span class="kd">on</span><span class="py">e</span><span class="w"> </span><span class="py">celebrity</span><span class="w"> </span><span class="py">node</span><span class="w"> </span><span class="py">with</span><span class="w"> </span><span class="py">1M</span><span class="w"> </span><span class="py">edges</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="nc">Create</span><span class="w"> </span><span class="py">follower</span><span class="w"> </span><span class="py">buckets</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">(</span><span class="py">celebrity</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">HAS_FOLLOWER_BUCKET</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">bucket</span><span class="p">:</span><span class="nc">FollowerBucket</span><span class="w"> </span><span class="p">{</span><span class="py">range</span><span class="p">:</span><span class="w"> </span><span class="s">"A-F"</span><span class="p">})</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">(</span><span class="nc">bucket</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">CONTAINS_FOLLOWER</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">follower</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w">
</span></span></span></code></pre></div><p><strong>Impact</strong>: <strong>Avoid O(n) expansion</strong> on supernodes.</p>
<hr>
<h4 id="issue-4-inefficient-aggregations" class="position-relative d-flex align-items-center group">
<span>Issue 4: Inefficient Aggregations</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="issue-4-inefficient-aggregations"
aria-haspopup="dialog"
aria-label="Share link: Issue 4: Inefficient Aggregations">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p><strong>Symptom</strong>: COUNT, SUM, AVG queries are slow.</p>
<p><strong>Example</strong>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">count</span><span class="p">(</span><span class="py">p</span><span class="p">)</span><span class="err">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Scans</span><span class="w"> </span><span class="py">all</span><span class="w"> </span><span class="py">Person</span><span class="w"> </span><span class="py">nodes</span><span class="w">
</span></span></span></code></pre></div><p><strong>Solution 1</strong>: Maintain counts in metadata node.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">stats</span><span class="p">:</span><span class="nc">Statistics</span><span class="w"> </span><span class="p">{</span><span class="kd">type</span><span class="p">:</span><span class="w"> </span><span class="s">"Person"</span><span class="p">})</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nc">RETURN</span><span class="w"> </span><span class="nc">stats</span><span class="err">.</span><span class="py">total_count</span><span class="err">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Update</span><span class="w"> </span><span class="kd">on</span><span class="w"> </span><span class="py">create</span><span class="err">/</span><span class="py">delete</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">stats</span><span class="p">:</span><span class="nc">Statistics</span><span class="w"> </span><span class="p">{</span><span class="kd">type</span><span class="p">:</span><span class="w"> </span><span class="s">"Person"</span><span class="p">})</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nc">SET</span><span class="w"> </span><span class="nc">stats</span><span class="err">.</span><span class="py">total_count</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">stats</span><span class="err">.</span><span class="py">total_count</span><span class="w"> </span><span class="err">+</span><span class="w"> </span><span class="py">1</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div><p><strong>Solution 2</strong>: Use index-backed aggregation (if supported).</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">CREATE</span><span class="w"> </span><span class="py">INDEX</span><span class="w"> </span><span class="py">person_label</span><span class="w"> </span><span class="py">ON</span><span class="w"> </span><span class="py">Person</span><span class="p">(</span><span class="py">label</span><span class="p">)</span><span class="err">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Future</span><span class="p">:</span><span class="w"> </span><span class="nc">Optimizer</span><span class="w"> </span><span class="py">uses</span><span class="w"> </span><span class="py">index</span><span class="w"> </span><span class="py">stats</span><span class="w"> </span><span class="py">for</span><span class="w"> </span><span class="py">count</span><span class="w">
</span></span></span></code></pre></div><p><strong>Impact</strong>: <strong>Constant time vs O(n)</strong> for large datasets.</p>
<hr>
<h4 id="issue-5-unindexed-joins" class="position-relative d-flex align-items-center group">
<span>Issue 5: Unindexed JOINs</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="issue-5-unindexed-joins"
aria-haspopup="dialog"
aria-label="Share link: Issue 5: Unindexed JOINs">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p><strong>Symptom</strong>: Queries joining on properties without indexes are slow.</p>
<p><strong>Example</strong>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">order</span><span class="p">:</span><span class="nc">Order</span><span class="p">),</span><span class="w"> </span><span class="p">(</span><span class="py">customer</span><span class="p">:</span><span class="nc">Customer</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">order</span><span class="err">.</span><span class="py">customer_id</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">customer</span><span class="err">.</span><span class="py">id</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">order</span><span class="err">.</span><span class="py">id</span><span class="p">,</span><span class="w"> </span><span class="py">customer</span><span class="err">.</span><span class="py">name</span><span class="err">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Cartesian</span><span class="w"> </span><span class="py">product</span><span class="p">:</span><span class="w"> </span><span class="nc">orders</span><span class="w"> </span><span class="err">×</span><span class="w"> </span><span class="py">customers</span><span class="p">!</span><span class="w">
</span></span></span></code></pre></div><p><strong>Solution 1</strong>: Use explicit relationships.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">order</span><span class="p">:</span><span class="nc">Order</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">PLACED_BY</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">customer</span><span class="p">:</span><span class="nc">Customer</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">order</span><span class="err">.</span><span class="py">id</span><span class="p">,</span><span class="w"> </span><span class="py">customer</span><span class="err">.</span><span class="py">name</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div><p><strong>Solution 2</strong>: If relationships don’t exist, create indexes.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">CREATE</span><span class="w"> </span><span class="py">INDEX</span><span class="w"> </span><span class="py">order_customer_id</span><span class="w"> </span><span class="py">ON</span><span class="w"> </span><span class="py">Order</span><span class="p">(</span><span class="py">customer_id</span><span class="p">)</span><span class="err">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CREATE</span><span class="w"> </span><span class="py">INDEX</span><span class="w"> </span><span class="py">customer_id</span><span class="w"> </span><span class="py">ON</span><span class="w"> </span><span class="py">Customer</span><span class="p">(</span><span class="py">id</span><span class="p">)</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div><p><strong>Impact</strong>: Avoids expensive Cartesian products.</p>
<hr>
<h3 id="performance-checklist" class="position-relative d-flex align-items-center group">
<span>Performance Checklist</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="performance-checklist"
aria-haspopup="dialog"
aria-label="Share link: Performance Checklist">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3>
<h4 id="before-query-execution" class="position-relative d-flex align-items-center group">
<span>Before Query Execution</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="before-query-execution"
aria-haspopup="dialog"
aria-label="Share link: Before Query Execution">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><ul>
<li><input disabled="" type="checkbox"> <strong>Use EXPLAIN</strong> to review execution plan</li>
<li><input disabled="" type="checkbox"> <strong>Check for NodeScan</strong> - add indexes if needed</li>
<li><input disabled="" type="checkbox"> <strong>Verify index usage</strong> - IndexSeek is ideal</li>
<li><input disabled="" type="checkbox"> <strong>Look for expensive sorts</strong> - consider index on ORDER BY property</li>
<li><input disabled="" type="checkbox"> <strong>Identify Cartesian products</strong> - use relationships instead</li>
</ul>
<h4 id="after-query-execution" class="position-relative d-flex align-items-center group">
<span>After Query Execution</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="after-query-execution"
aria-haspopup="dialog"
aria-label="Share link: After Query Execution">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><ul>
<li><input disabled="" type="checkbox"> <strong>Use PROFILE</strong> to measure actual performance</li>
<li><input disabled="" type="checkbox"> <strong>Compare execution_time_ms</strong> to expectations</li>
<li><input disabled="" type="checkbox"> <strong>Check rows_returned</strong> - is it what you expected?</li>
<li><input disabled="" type="checkbox"> <strong>Verify index hit</strong> - did optimizer use your index?</li>
<li><input disabled="" type="checkbox"> <strong>Re-measure after optimization</strong> - confirm improvement</li>
</ul>
<h4 id="index-strategy" class="position-relative d-flex align-items-center group">
<span>Index Strategy</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="index-strategy"
aria-haspopup="dialog"
aria-label="Share link: Index Strategy">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><ul>
<li><input disabled="" type="checkbox"> <strong>Index frequently filtered properties</strong></li>
<li><input disabled="" type="checkbox"> <strong>Index ORDER BY properties</strong></li>
<li><input disabled="" type="checkbox"> <strong>Use hash indexes for exact lookups</strong></li>
<li><input disabled="" type="checkbox"> <strong>Use fulltext indexes for text search</strong></li>
<li><input disabled="" type="checkbox"> <strong>Use vector indexes for similarity search</strong></li>
<li><input disabled="" type="checkbox"> <strong>Don’t over-index</strong> - each index adds write overhead</li>
</ul>
<hr>
<h3 id="advanced-optimization-techniques" class="position-relative d-flex align-items-center group">
<span>Advanced Optimization Techniques</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="advanced-optimization-techniques"
aria-haspopup="dialog"
aria-label="Share link: Advanced Optimization Techniques">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3>
<h4 id="materialized-views" class="position-relative d-flex align-items-center group">
<span>Materialized Views</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="materialized-views"
aria-haspopup="dialog"
aria-label="Share link: Materialized Views">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p>For expensive aggregations run frequently, precompute results:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Instead</span><span class="w"> </span><span class="py">of</span><span class="w"> </span><span class="py">computing</span><span class="w"> </span><span class="kd">on</span><span class="w"> </span><span class="py">every</span><span class="w"> </span><span class="kd">query</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nc">MATCH</span><span class="w"> </span><span class="p">(</span><span class="nc">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">WORKS_FOR</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">c</span><span class="p">:</span><span class="nc">Company</span><span class="w"> </span><span class="p">{</span><span class="py">name</span><span class="p">:</span><span class="w"> </span><span class="s">"Acme"</span><span class="p">})</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nc">RETURN</span><span class="w"> </span><span class="py">count</span><span class="p">(</span><span class="py">p</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">employee_count</span><span class="err">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Maintain</span><span class="w"> </span><span class="py">a</span><span class="w"> </span><span class="py">cached</span><span class="w"> </span><span class="py">value</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nc">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">c</span><span class="p">:</span><span class="nc">Company</span><span class="w"> </span><span class="p">{</span><span class="py">name</span><span class="p">:</span><span class="w"> </span><span class="s">"Acme"</span><span class="p">})</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nc">RETURN</span><span class="w"> </span><span class="py">c</span><span class="err">.</span><span class="py">employee_count</span><span class="err">;</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Updated</span><span class="w"> </span><span class="kd">on</span><span class="w"> </span><span class="py">hire</span><span class="err">/</span><span class="py">termination</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="query-result-caching" class="position-relative d-flex align-items-center group">
<span>Query Result Caching</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="query-result-caching"
aria-haspopup="dialog"
aria-label="Share link: Query Result Caching">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p>Cache frequent query results at application level:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">functools</span> <span class="kn">import</span> <span class="n">lru_cache</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nd">@lru_cache</span><span class="p">(</span><span class="n">maxsize</span><span class="o">=</span><span class="mi">128</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">get_company_employees</span><span class="p">(</span><span class="n">company_name</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">db</span><span class="o">.</span><span class="n">query</span><span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"MATCH (p:Person)-[:WORKS_FOR]->(c:Company {name: $name}) RETURN p"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="p">{</span><span class="s2">"name"</span><span class="p">:</span> <span class="n">company_name</span><span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="p">)</span>
</span></span></code></pre></div>
<h4 id="batch-operations" class="position-relative d-flex align-items-center group">
<span>Batch Operations</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="batch-operations"
aria-haspopup="dialog"
aria-label="Share link: Batch Operations">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p>Instead of N queries, use one batched query:</p>
<p><strong>❌ Bad (N+1 Query Problem)</strong>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">for</span> <span class="n">order_id</span> <span class="ow">in</span> <span class="n">order_ids</span><span class="p">:</span> <span class="c1"># 1000 orders</span>
</span></span><span class="line"><span class="cl"> <span class="n">result</span> <span class="o">=</span> <span class="n">db</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">"MATCH (o:Order {id: $id}) RETURN o"</span><span class="p">,</span> <span class="p">{</span><span class="s2">"id"</span><span class="p">:</span> <span class="n">order_id</span><span class="p">})</span>
</span></span><span class="line"><span class="cl"> <span class="c1"># 1000 individual queries!</span>
</span></span></code></pre></div><p><strong>✅ Good (Batch Query)</strong>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">result</span> <span class="o">=</span> <span class="n">db</span><span class="o">.</span><span class="n">query</span><span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"MATCH (o:Order) WHERE o.id IN $ids RETURN o"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="p">{</span><span class="s2">"ids"</span><span class="p">:</span> <span class="n">order_ids</span><span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Single query</span>
</span></span></code></pre></div><hr>
<h3 id="monitoring-query-performance" class="position-relative d-flex align-items-center group">
<span>Monitoring Query Performance</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="monitoring-query-performance"
aria-haspopup="dialog"
aria-label="Share link: Monitoring Query Performance">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3>
<h4 id="enable-query-logging" class="position-relative d-flex align-items-center group">
<span>Enable Query Logging</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="enable-query-logging"
aria-haspopup="dialog"
aria-label="Share link: Enable Query Logging">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="c"># geode.yaml</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">logging</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">level</span><span class="p">:</span><span class="w"> </span><span class="s1">'info'</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">slow_query_threshold_ms</span><span class="p">:</span><span class="w"> </span><span class="m">1000</span><span class="w"> </span><span class="c"># Log queries > 1s</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="prometheus-metrics" class="position-relative d-flex align-items-center group">
<span>Prometheus Metrics</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="prometheus-metrics"
aria-haspopup="dialog"
aria-label="Share link: Prometheus Metrics">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Query duration histogram</span>
</span></span><span class="line"><span class="cl">geode_query_duration_seconds_bucket<span class="o">{</span><span class="nv">le</span><span class="o">=</span><span class="s2">"0.1"</span><span class="o">}</span>
</span></span><span class="line"><span class="cl">geode_query_duration_seconds_bucket<span class="o">{</span><span class="nv">le</span><span class="o">=</span><span class="s2">"1.0"</span><span class="o">}</span>
</span></span><span class="line"><span class="cl">geode_query_duration_seconds_bucket<span class="o">{</span><span class="nv">le</span><span class="o">=</span><span class="s2">"10.0"</span><span class="o">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Query rate</span>
</span></span><span class="line"><span class="cl">rate<span class="o">(</span>geode_queries_total<span class="o">[</span>5m<span class="o">])</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 95th percentile latency</span>
</span></span><span class="line"><span class="cl">histogram_quantile<span class="o">(</span>0.95, rate<span class="o">(</span>geode_query_duration_seconds_bucket<span class="o">[</span>5m<span class="o">]))</span>
</span></span></code></pre></div>
<h4 id="grafana-dashboard-queries" class="position-relative d-flex align-items-center group">
<span>Grafana Dashboard Queries</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="grafana-dashboard-queries"
aria-haspopup="dialog"
aria-label="Share link: Grafana Dashboard Queries">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-promql" data-lang="promql"><span class="line"><span class="cl"><span class="c1"># Top 5 slowest query types</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">topk</span><span class="o">(</span><span class="mi">5</span><span class="p">,</span><span class="w"> </span><span class="k">avg</span><span class="o">(</span><span class="kr">rate</span><span class="o">(</span><span class="nv">geode_query_duration_seconds_sum</span><span class="p">[</span><span class="s">5m</span><span class="p">]</span><span class="o">))</span><span class="w"> </span><span class="k">by</span><span class="w"> </span><span class="o">(</span><span class="nv">query_type</span><span class="o">))</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1"># Query throughput</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">sum</span><span class="o">(</span><span class="kr">rate</span><span class="o">(</span><span class="nv">geode_queries_total</span><span class="p">[</span><span class="s">5m</span><span class="p">]</span><span class="o">))</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1"># Error rate</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kr">rate</span><span class="o">(</span><span class="nv">geode_query_errors_total</span><span class="p">[</span><span class="s">5m</span><span class="p">]</span><span class="o">)</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="kr">rate</span><span class="o">(</span><span class="nv">geode_queries_total</span><span class="p">[</span><span class="s">5m</span><span class="p">]</span><span class="o">)</span><span class="w">
</span></span></span></code></pre></div><hr>
<h3 id="next-steps" class="position-relative d-flex align-items-center group">
<span>Next Steps</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="next-steps"
aria-haspopup="dialog"
aria-label="Share link: Next Steps">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3><ul>
<li><a
href="/docs/query/indexing-and-optimization/"
>Indexing Guide</a>
- Complete index reference</li>
<li><a
href="/docs/model/data-model-and-types/"
>Data Model</a>
- Type system and schema design</li>
<li><a
href="/docs/guides/troubleshooting/"
>Troubleshooting</a>
- Diagnose performance issues</li>
<li><a
href="/docs/configuration/server-configuration/"
>Configuration</a>
- Tune server performance</li>
<li><a
href="/docs/ops/observability/"
>Monitoring</a>
- Set up performance monitoring</li>
</ul>
Query Performance Tuning Guide
Complete guide to analyzing and optimizing Geode query performance using EXPLAIN, PROFILE, indexes, and the cost-based optimizer with BM25 integration.