๐ What is Multi-Level Indexing?
A Multi-Level Index is an advanced indexing technique used when the primary (or secondary) index is too large to be stored in main memory or searched efficiently.
Instead of storing one huge index, the index itself is broken down into multiple levels of indexes, forming a hierarchical structure โ like a tree.
๐ Why Multi-Level Indexing?
When:
A single-level index becomes too large
Searching even the index becomes slow
We want to reduce disk I/O and search time
โ Multi-level indexing improves performance by applying indexing on the index itself.
๐ง Example:
Letโs say we have 1,000,000 records, and a dense primary index stores every 100th record.
That gives 10,000 entries in Level 0 (main index)
We index every 100th entry of this index โ Level 1 with 100 entries
Again index every 10th entry of Level 1 โ Level 2 with 10 entries
Now, instead of scanning 10,000 entries, we:
Use Level 2 to find the block in Level 1
Use Level 1 to find the block in Level 0
Use Level 0 to go to the exact data block
๐ This reduces search time from O(n) to O(log n) like a tree traversal.
๐ง Characteristics
Feature | Description |
|---|---|
๐ฏ Purpose | Improve efficiency of large indexes |
๐งฑ Structure | Hierarchical (multi-level) |
โ๏ธ Access Time | Faster than single-level index |
๐ฆ Space Overhead | Slightly more than single-level index |
๐ Ideal For | Large tables and huge datasets |
๐ Comparison with Single-Level Index
Feature | Single-Level Index | Multi-Level Index |
|---|---|---|
Index Size | Can be large | Broken into manageable levels |
Speed | Slower for large data | Faster due to log-like search |
Memory Usage | High | More efficient |
Search Time | Linear or binary | Logarithmic |
๐ก Analogy:
Think of a library:
๐ Shelves โ Data blocks
๐๏ธ Shelf catalog โ Main index (Level 0)
๐ Floor directory โ Level 1
๐ข Building directory โ Level 2
You donโt search all books โ you follow the hierarchy to find the exact shelf!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Multi-Level Indexing โ Try It Yourself</title>
<style>
.infographic-multilevel {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--line: #ddd6c9;
--good: #16a34a;
--good-soft: #dcfce7;
--display-font: Georgia, 'Iowan Old Style', serif;
--body-font: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
--mono-font: 'SF Mono', Consolas, monospace;
background: var(--paper);
color: var(--ink);
font-family: var(--body-font);
max-width: 980px;
margin: 0 auto;
box-sizing: border-box;
overflow-x: hidden;
}
.infographic-multilevel[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--accent: #5b8def;
--accent-soft:#202942;
--line: #2c313d;
--good: #4ade80;
--good-soft: #123420;
}
.infographic-multilevel * { box-sizing: border-box; }
.ml-head { text-align: center; margin-bottom: 0.25rem; }
.ml-head h2 {
font-family: var(--display-font);
font-size: 1.95rem;
margin: 0 0 0.5rem;
}
.ml-head p {
color: var(--ink-soft);
font-size: 1rem;
margin: 0 auto;
max-width: 620px;
line-height: 1.55;
}
.ml-scale-row {
display: flex;
justify-content: center;
gap: 0.6rem;
flex-wrap: wrap;
margin-top: 1.5rem;
}
.ml-scale-chip {
font-size: 0.78rem;
background: var(--paper-alt);
border: 1px solid var(--line);
border-radius: 999px;
padding: 0.4rem 0.85rem;
color: var(--ink-soft);
}
.ml-scale-chip b { color: var(--accent); }
.ml-toy-note {
text-align: center;
font-size: 0.85rem;
color: var(--ink-soft);
margin-top: 1.1rem;
font-style: italic;
}
.ml-breadcrumb {
display: flex;
justify-content: center;
gap: 0.4rem;
flex-wrap: wrap;
margin-top: 1.1rem;
font-family: var(--mono-font);
font-size: 0.82rem;
color: var(--ink-soft);
}
.ml-breadcrumb .seg { background: var(--accent-soft); color: var(--accent); border-radius: 6px; padding: 0.2rem 0.55rem; }
.ml-level {
margin-top: 1.5rem;
background: var(--paper-alt);
border: 1px solid var(--line);
border-radius: 10px;
padding: 1.1rem;
}
.ml-level-title { font-family: var(--display-font); font-size: 1rem; margin: 0 0 0.3rem; }
.ml-level-sub { font-size: 0.8rem; color: var(--ink-soft); margin: 0 0 0.85rem; }
.ml-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(80px, 1fr)); gap: 0.5rem; }
.ml-entry {
font-family: var(--mono-font);
font-size: 0.8rem;
background: var(--paper);
border: 1px solid var(--line);
border-radius: 6px;
padding: 0.5rem 0.4rem;
text-align: center;
cursor: pointer;
transition: border-color 0.15s, background 0.15s, transform 0.15s;
}
.ml-entry:hover { border-color: var(--accent); }
.ml-entry.is-chosen { background: var(--accent); color: #fff; border-color: var(--accent); transform: scale(1.05); }
.ml-found {
margin-top: 1.5rem;
background: var(--good-soft);
color: var(--good);
border-radius: 10px;
padding: 1rem 1.25rem;
text-align: center;
display: none;
}
.ml-found.is-visible { display: block; }
.ml-found b { font-family: var(--mono-font); }
.ml-stats {
display: flex;
gap: 1rem;
justify-content: center;
margin-top: 1.5rem;
flex-wrap: wrap;
}
.ml-stat {
background: var(--paper-alt);
border: 1px solid var(--line);
border-radius: 8px;
padding: 0.7rem 1.1rem;
text-align: center;
min-width: 170px;
}
.ml-stat.is-winner { border-color: var(--good); }
.ml-stat-label { font-size: 0.75rem; color: var(--ink-soft); text-transform: uppercase; letter-spacing: 0.04em; }
.ml-stat-value { font-family: var(--mono-font); font-size: 1.3rem; margin-top: 0.2rem; color: var(--accent); }
.ml-stat.is-winner .ml-stat-value { color: var(--good); }
.ml-controls-row { display: flex; justify-content: center; margin-top: 1.25rem; }
.ml-reset-btn {
font: inherit;
font-size: 0.82rem;
background: var(--paper);
border: 1px solid var(--line);
border-radius: 7px;
padding: 0.45rem 0.9rem;
cursor: pointer;
color: var(--ink);
}
.ml-reset-btn:hover { border-color: var(--accent); }
@media (prefers-reduced-motion: reduce) {
.infographic-multilevel *, .infographic-multilevel *::before, .infographic-multilevel *::after {
transition-duration: 0.001ms !important;
animation-duration: 0.001ms !important;
}
}
</style>
</head>
<body>
<div class="infographic-multilevel" id="multilevel">
<div class="ml-head">
<h2>Multi-Level Indexing โ Try It Yourself</h2>
<p>Indexing the index, applied again and again, turns a long linear search into a short series of jumps.</p>
</div>
<div class="ml-scale-row">
<span class="ml-scale-chip"><b>1,000,000</b> records</span>
<span class="ml-scale-chip">โ Level 0: <b>10,000</b> entries</span>
<span class="ml-scale-chip">โ Level 1: <b>100</b> entries</span>
<span class="ml-scale-chip">โ Level 2: <b>10</b> entries</span>
</div>
<p class="ml-toy-note">Too many to click through, so here's a small 10ร10ร10 version โ same idea, same three jumps.</p>
<div class="ml-breadcrumb" id="mlBreadcrumb">
<span class="seg">Level 2</span>
</div>
<div class="ml-level" id="mlLevel2">
<p class="ml-level-title">Level 2 (top)</p>
<p class="ml-level-sub">10 entries โ click one to drill into its Level 1 block.</p>
<div class="ml-grid" id="mlGrid2"></div>
</div>
<div class="ml-level" id="mlLevel1" style="display:none;">
<p class="ml-level-title">Level 1</p>
<p class="ml-level-sub" id="mlSub1"></p>
<div class="ml-grid" id="mlGrid1"></div>
</div>
<div class="ml-level" id="mlLevel0" style="display:none;">
<p class="ml-level-title">Level 0</p>
<p class="ml-level-sub" id="mlSub0"></p>
<div class="ml-grid" id="mlGrid0"></div>
</div>
<div class="ml-found" id="mlFound"></div>
<div class="ml-stats">
<div class="ml-stat" id="mlStatMulti">
<div class="ml-stat-label">Multi-level jumps</div>
<div class="ml-stat-value" id="mlJumpCount">0 / 3</div>
</div>
<div class="ml-stat">
<div class="ml-stat-label">Flat scan of Level 0 (10,000)</div>
<div class="ml-stat-value">~14 compares</div>
</div>
</div>
<div class="ml-controls-row">
<button class="ml-reset-btn" id="mlAutoRun" type="button" style="background:var(--accent); color:#fff; border-color:var(--accent);">๐ Auto-run search (one click)</button>
<button class="ml-reset-btn" id="mlReset" type="button" style="margin-left:0.6rem;">Reset</button>
</div>
</div>
<script>
(function () {
const wrapper = document.getElementById('multilevel');
const bodyAttr = document.body.getAttribute('data-darkmode');
let dark;
if (bodyAttr === 'true') {
dark = true;
} else if (bodyAttr === 'false') {
dark = false;
} else {
const match = document.cookie.match(/(?:^|;\s*)darkMode=([^;]+)/);
dark = match ? match[1] === 'true' : false;
}
if (dark) wrapper.setAttribute('data-theme', 'dark');
})();
(function () {
const grid2 = document.getElementById('mlGrid2');
const grid1 = document.getElementById('mlGrid1');
const grid0 = document.getElementById('mlGrid0');
const level1El = document.getElementById('mlLevel1');
const level0El = document.getElementById('mlLevel0');
const sub1 = document.getElementById('mlSub1');
const sub0 = document.getElementById('mlSub0');
const breadcrumb = document.getElementById('mlBreadcrumb');
const found = document.getElementById('mlFound');
const jumpCount = document.getElementById('mlJumpCount');
const statMulti = document.getElementById('mlStatMulti');
let jumps = 0;
let chosen2 = null, chosen1 = null, chosen0 = null;
function buildGrid(container, count, onPick) {
container.innerHTML = '';
for (let i = 1; i <= count; i++) {
const el = document.createElement('div');
el.className = 'ml-entry';
el.textContent = 'Block ' + i;
el.addEventListener('click', () => onPick(i, el, container));
container.appendChild(el);
}
}
function selectEntry(container, el) {
container.querySelectorAll('.ml-entry').forEach(e => e.classList.remove('is-chosen'));
el.classList.add('is-chosen');
}
function updateBreadcrumb() {
let html = '<span class="seg">Level 2' + (chosen2 ? ': Block ' + chosen2 : '') + '</span>';
if (chosen2) html += '<span class="seg">Level 1' + (chosen1 ? ': Block ' + chosen1 : '') + '</span>';
if (chosen1) html += '<span class="seg">Level 0' + (chosen0 ? ': Block ' + chosen0 : '') + '</span>';
if (chosen0) html += '<span class="seg">๐ Data block found</span>';
breadcrumb.innerHTML = html;
}
function updateStats() {
jumpCount.textContent = jumps + ' / 3';
statMulti.classList.toggle('is-winner', jumps === 3);
}
buildGrid(grid2, 10, (i, el, container) => {
chosen2 = i;
chosen1 = null;
chosen0 = null;
selectEntry(container, el);
jumps = 1;
level1El.style.display = 'block';
level0El.style.display = 'none';
found.classList.remove('is-visible');
sub1.textContent = 'Inside Level 2 โ Block ' + i + '. 10 entries โ click one to drill into Level 0.';
buildGrid(grid1, 10, (j, el2, container2) => {
chosen1 = j;
chosen0 = null;
selectEntry(container2, el2);
jumps = 2;
level0El.style.display = 'block';
found.classList.remove('is-visible');
sub0.textContent = 'Inside Level 1 โ Block ' + j + '. 10 entries โ click one to reach the data block.';
buildGrid(grid0, 10, (k, el3, container3) => {
chosen0 = k;
selectEntry(container3, el3);
jumps = 3;
found.innerHTML = '๐ฏ Reached the data block in <b>3 jumps</b> โ Level 2 โ Level 1 โ Level 0 โ data, instead of scanning through thousands of entries.';
found.classList.add('is-visible');
updateBreadcrumb();
updateStats();
});
updateBreadcrumb();
updateStats();
});
updateBreadcrumb();
updateStats();
});
document.getElementById('mlReset').addEventListener('click', () => {
chosen2 = chosen1 = chosen0 = null;
jumps = 0;
level1El.style.display = 'none';
level0El.style.display = 'none';
found.classList.remove('is-visible');
grid2.querySelectorAll('.ml-entry').forEach(e => e.classList.remove('is-chosen'));
updateBreadcrumb();
updateStats();
});
function randomChild(container) {
const children = container.querySelectorAll('.ml-entry');
return children[Math.floor(Math.random() * children.length)];
}
document.getElementById('mlAutoRun').addEventListener('click', function () {
this.disabled = true;
document.getElementById('mlReset').click();
setTimeout(() => {
randomChild(grid2).click();
setTimeout(() => {
randomChild(grid1).click();
setTimeout(() => {
randomChild(grid0).click();
this.disabled = false;
found.scrollIntoView({ behavior: 'smooth', block: 'center' });
}, 700);
}, 700);
}, 300);
});
updateBreadcrumb();
updateStats();
})();
</script>
</body>
</html>.demo {
font-family: system-ui, sans-serif;
padding: 16px;
}
.demo h1 {
color: #2563eb;
margin: 0 0 8px;
}
.demo p {
color: #4b5563;
margin: 0;
}document.querySelector('.demo h1')?.addEventListener('click', () => {
alert('Hello from live preview!');
});๐งฎ Formula:
If:
n= total number of recordsb= number of index entries per block
Then the number of index levels required =
โ log<sub>b</sub>(n) โ
โ Summary:
Multi-Level Index = Index on index (tree-like)
Used when the index is too large to be searched efficiently
Reduces disk access and improves search time
Commonly used with B+ Trees in modern DBMS