Che cos'è un indice del database?

Aggiornato: ottobre 2026

Un indice del database è una struttura di ricerca ordinata che permette al motore di trovare le righe corrispondenti senza scansionare l’intera tabella. L’analogia del libro è esatta: nessuno trova “idempotenza” in un volume di 900 pagine leggendolo – si consulta l’indice e si salta alla pagina. I database fanno la stessa scelta a ogni query, e il fatto che possano saltare o no è la differenza più comune tra una query da 5 millisecondi e una da 5 secondi.

Punti chiave

DomandaRisposta
Che cos’èUna struttura ordinata a lato: valori + puntatori, come l’indice di un libro
Il guadagnoRicerca logaritmica invece di scansione lineare – decisiva su larga scala
La tassaOgni scrittura aggiorna ogni indice; l’archiviazione cresce
Che cosa indicizzareColonne di filtro, di join/puntatore e di ordinamento – se selettive
La diagnosiEXPLAIN: una scansione completa su una tabella grande è la spia

L’indice, creato e percepito

-- Il cavallo da tiro: un indice composito sagomato sulla query calda
CREATE INDEX orders_pending ON orders (status, created_at);

-- Specializzazioni della stessa idea:
CREATE UNIQUE INDEX users_email ON users (email);         -- vincolo + velocità
CREATE INDEX unshipped ON orders (created_at)
  WHERE shipped = false;                                  -- parziale: solo il sottoinsieme caldo

-- Il prima/dopo, visto dal piano:
EXPLAIN SELECT * FROM orders WHERE status = 'pending' AND created_at > now() - interval '1 day';
--  prima:   Seq Scan on orders   (righe esaminate: 4.812.309)
--  dopo:    Index Scan using orders_pending   (righe esaminate: 1.214)

Il codice applicativo incontra la stessa fisica attraverso la forma della query – questa query è la specifica dell’indice (status, createdAt), qualunque sia la superficie che la scrive:

// JavaScript / Node.js — Back4app JS SDK
// The query shape tells you the index: (status, createdAt)
const query = new Parse.Query('Order');
query.equalTo('status', 'pending');       // equality first…
query.greaterThan('createdAt', since);    // …then the range
query.descending('createdAt');            // …sorted by the same column
const backlog = await query.find();
// Indexed: milliseconds at any size. Unindexed: a full collection scan.

Come funziona il salto

Una ricerca in un indice B-treeUna query scende un albero ordinato e poco profondo dalla radice, passando per un nodo intermedio, fino a una foglia che contiene il valore cercato e i puntatori alle righe, toccando una manciata di pagine invece di scansionare l'intera tabella.

Nodo radice
(intervalli)

Ramo
A–M

Ramo
N–Z

Foglia: 'pending' → righe 88, 1042, 55913

Foglia …

Recupera esattamente quelle righe

Una query scende un albero ordinato e poco profondo dalla radice, passando per un nodo intermedio, fino a una foglia che contiene il valore cercato e i puntatori alle righe, toccando una manciata di pagine invece di scansionare l'intera tabella.

La struttura predefinita, in ogni motore, è il B-tree: poco profondo, ordinato, auto-bilanciato – tre o quattro livelli coprono centinaia di milioni di voci, e le sue foglie sono concatenate, ed è per questo che una sola struttura serve allo stesso modo uguaglianza, intervalli e ORDER BY. È questa versatilità a rendere “nel dubbio, B-tree” il consiglio permanente, con le alternative nel ruolo di specialiste.

B-tree vs. hash vs. gli specialisti

Quale tipo di indice conviene usare?

TipoSupportaSceglierlo quando
B-tree (predefinito)=, <, >, intervalli, ordinamenti, prefissiQuasi sempre – il generalista
HashSolo uguaglianza, O(1)Ricerche per corrispondenza esatta, nient’altro
CompositoMulti-colonna, prefisso sinistroLa query calda filtra su più colonne
UnivocoB-tree + nessun duplicatoVincolo e indice in uno
ParzialeUna fetta filtrata di righeSottoinsiemi caldi: non spedito, non letto, attivo
Di coperturaQuery risolta dal solo indiceQuery a prevalenza di lettura con un elenco di colonne stabile
Full-text (invertito)Parole → documentiCaselle di ricerca
GeospazialePunti, regioni, distanzaQuery “vicino a me”

Due regole reggono la riga del composito: la regola del prefisso sinistro – un indice su (a, b, c) serve a, (a, b), (a, b, c), mai b da solo – e prima l’uguaglianza, intervallo e ordinamento per ultimi nell’ordine delle colonne (il mnemonico ESR dell’indicizzazione nei database documentali, dove gli stessi B-tree fanno lo stesso lavoro).

Quando indicizzare – e quando no

Indicizzare: le colonne nei filtri WHERE frequenti; le chiavi di join e i campi puntatore (alcuni motori non indicizzano mai le chiavi esterne in automatico – un classico della scansione silenziosa); le colonne ORDER BY sui percorsi caldi; e sempre con la selettività in mente – una colonna email (milioni di valori distinti) si guadagna il posto, un flag di stato (tre valori) di norma no da solo, anche se brilla in testa a un composito con un intervallo dietro. Non indicizzare: le tabelle piccole che il motore scansiona più in fretta di quanto cerchi; le tabelle calde in scrittura oltre i pochi indici essenziali; le colonne già servite dal prefisso sinistro di un indice esistente; e tutto ciò per cui non si sa nominare una query – un indice senza query è pura tassa sulle scritture. Il ciclo di verifica: passare EXPLAIN sulle query lente in cerca di scansioni, controllare le statistiche di utilizzo per trovare gli indici morti, aggiungere ed eliminare di conseguenza.

Casi d’uso tipici

  • La query della lista calda. Filtri su stato più data dietro ogni dashboard e ogni feed – il terreno di casa dell’indice composito.
  • Campi di accesso e di ricerca. Email, username, ID esterni – indici univoci che fanno vincolo e velocità in una mossa.
  • Percorsi di join e di puntatore. Ogni chiave esterna e ogni puntatore che le query attraversano; il complice silenzioso del problema N+1 è uno di questi non indicizzato.
  • Filtri multi-tenant. Compositi che iniziano dal tenant – la regola dell’architettura multi-tenant per cui ogni indice parte da tenant_id.
  • Ricerca e geo. Indici invertiti e spaziali che alimentano le query fuori portata dei B-tree.

Conviene aggiungere quell’indice? Matrice decisionale

Aggiungerlo quando…Lasciar perdere quando…
Una query frequente filtra o ordina su quella colonnaNessuna query in produzione la usa
EXPLAIN mostra scansioni su una tabella che cresceLa tabella è piccola e resta piccola
La colonna è selettiva (molti valori distinti)Il prefisso di un indice esistente la copre già
È una chiave di join o un campo puntatoreLa tabella è dominata dalle scritture e la lettura è rara
Serve comunque imporre una regola di univocitàSi sta tirando a indovinare: prima misurare

La disciplina in una frase: gli indici si creano in risposta alle query, si rivedono rispetto all’uso effettivo e si eliminano senza sentimentalismi.

Limiti e trade-off

  • Le scritture pagano le letture. Ogni indice è un’altra struttura che ogni scrittura deve mantenere – i caricamenti in massa, com’è noto, vanno più veloci con gli indici eliminati prima e ricostruiti dopo.
  • L’archiviazione è reale. Gli indici rivaleggiano spesso con la dimensione della tabella stessa; quelli di copertura in particolare barattano disco per velocità.
  • Decide l’ottimizzatore, non chi scrive la query. Un indice poco selettivo può essere ignorato a ragione; statistiche stantie possono far ignorare a torto un indice buono – il piano è la verità.
  • Gli errori di ordine neutralizzano i compositi. (created_at, status) e (status, created_at) sono strumenti diversi; la regola del prefisso sinistro non perdona nulla.
  • Gli indici non aggiustano la query. Wildcard iniziali, funzioni applicate alle colonne e cicli N+1 sconfiggono l’indicizzazione dall’alto – la forma della query viene prima.

Indici su Back4app

Back4app è una piattaforma open-source di Backend as a Service (BaaS) che combina database gestito, API REST e GraphQL generate automaticamente, autenticazione, archiviazione di file e funzioni serverless con Cloud Code. La gestione degli indici vive accanto allo schema nella dashboard: si creano, si rivedono e si eliminano indici per classe – a campo singolo o composti – sull’archivio basato su MongoDB che le query dell’SDK interrogano davvero, seguendo la stessa logica dei B-tree e dell’ESR vista sopra. La query nelle schede di codice e l’indice che la serve si progettano nello stesso posto, che è esattamente dove vuole stare la disciplina di indicizzare ciò che si interroga.

Domande frequenti

Che cos'è un indice del database, in parole semplici?

Una struttura separata e ordinata – di solito un B-tree – che contiene i valori di una colonna più i puntatori alle loro righe, esattamente come l'indice analitico di un libro contiene i termini più i numeri di pagina. Il motore cerca il valore nella piccola struttura ordinata e salta direttamente alle righe corrispondenti, invece di leggere l'intera tabella sperando di trovarle.

Quanto è più veloce una query indicizzata?

È la differenza tra lavoro logaritmico e lavoro lineare: una ricerca in un B-tree tocca una manciata di pagine, sia che la tabella contenga diecimila righe sia che ne contenga cento milioni, mentre una scansione completa legge tutto. Alle piccole dimensioni entrambe sembrano istantanee – ed è per questo che gli indici mancanti si nascondono in sviluppo e detonano in produzione, dove la stessa query esamina all'improvviso milioni di righe.

Gli indici rallentano le scritture?

Sì – è questa la tassa. Ogni inserimento, aggiornamento o cancellazione su una colonna indicizzata deve aggiornare anche ogni indice che la riferisce: sei indici su una tabella significano fino a sei aggiornamenti di struttura in più per scrittura, oltre all'archiviazione che occupano. Gli indici sono un acquisto di velocità in lettura pagato in velocità di scrittura e in disco – quelli deliberati se lo guadagnano, quelli dimenticati si limitano a presentare il conto.

Quali colonne conviene indicizzare?

Le colonne che le query usano davvero: i filtri (WHERE), le chiavi di join – comprese le chiavi esterne e i campi puntatore, che alcuni motori non indicizzano automaticamente – e le colonne di ordinamento (ORDER BY). A questo va aggiunto il test della selettività: una colonna email che distingue milioni di righe si merita il proprio indice; un flag booleano che taglia la tabella in due, di norma, no.

In che ordine vanno le colonne di un indice composito?

Prima l'uguaglianza, poi intervalli e ordinamento – e va ricordata la regola del prefisso sinistro: un indice su (a, b, c) serve le query che filtrano su a, su a e b, o su tutte e tre, ma non su b da solo. La formulazione della stessa regola nei database documentali è ESR: Equality, Sort, Range. L'ordine delle colonne è la differenza tra un indice composito che funziona e un indice che si limita a esistere.

Come si trovano gli indici mancanti o inutilizzati?

Per quelli mancanti: si esegue il piano di esecuzione – EXPLAIN – e si cercano le scansioni complete sulle tabelle grandi; la colonna di filtro di una query lenta e frequente è la candidata. Per quelli inutilizzati: ogni motore tiene statistiche di utilizzo degli indici, e un indice che nessuna query ha toccato da mesi è pura tassa sulle scritture, da eliminare. Il piano e le statistiche, insieme, sono tutta la metodologia.

Che cosa sono gli indici univoci, parziali e di copertura?

Specializzazioni della stessa struttura: un indice univoco impone l'assenza di duplicati come vincolo e intanto accelera le ricerche; un indice parziale copre solo le righe che soddisfano una condizione – piccolo e rapido per i sottoinsiemi caldi come gli ordini non spediti; un indice di copertura contiene tutte le colonne di cui una query ha bisogno, così il motore risponde dal solo indice senza visitare la tabella.

L'indicizzazione funziona allo stesso modo nei database documentali?

Concettualmente identica – B-tree sui valori dei campi – con gli stessi trade-off e la stessa logica del prefisso sinistro sotto la regola empirica ESR. I database documentali aggiungono gli indici multikey sui campi array e le varianti geospaziali, e la regola operativa sopravvive alla traduzione: indicizzare ciò che si interroga, soprattutto i campi puntatore che join e include attraversano.

Termini correlati

Confronta con

Fonti di approfondimento

Pronto a costruire il tuo backend?

Avvia il tuo progetto su Back4app in pochi minuti: database, autenticazione, API e Cloud Code inclusi. Nessuna carta di credito richiesta.

Scritto e revisionato da Back4app Engineering, Back4app Engineering · Pubblicato il 2026-10-05