Ciao, e benvenuto nella sesta puntata della cinquantatreesima stagione. Oggi parliamo dell'idea più pratica di tutta la stagione, quella che, più di ogni altra, fa la differenza tra una base di dati fulminea e una lentissima. È semplice da capire, ed è ciò che il pianificatore di cui parlavamo cerca sempre di poter usare. Oggi capiamo gli indici.
Partiamo dal problema, perché è intuitivo. Immagina di avere una tabella con dieci milioni di clienti, e di cercarne uno per nome. Senza aiuti, Postgres non ha scelta: deve partire dalla prima riga e leggerle tutte, una per una, fino a trovare quella giusta, o fino alla fine per essere sicuro di averle viste tutte. Dieci milioni di righe lette per trovarne una. È come cercare una parola in un libro di mille pagine leggendolo dall'inizio. Funziona, ma è disperatamente lento, e diventa più lento a ogni cliente che aggiungi.
Voglio darti la soluzione, perché la conosci già dai libri. La soluzione è l'indice, ed è esattamente l'indice analitico in fondo a un libro. In un libro, se vuoi trovare dove si parla di un certo argomento, non leggi tutte le pagine: vai all'indice, che è ordinato in modo furbo, trovi la voce in un attimo, e leggi il numero di pagina. Un indice di una base di dati fa lo stesso: è una struttura a parte, ordinata, che dice a Postgres dove si trova ogni valore, così che possa saltare dritto alla riga giusta senza leggere tutte le altre. Da dieci milioni di righe lette, a una manciata.
Voglio dirti quanto è grande questa differenza, perché è quasi incredibile. Non stiamo parlando di essere il doppio più veloci. Con i numeri grandi, un indice può rendere una ricerca migliaia o milioni di volte più rapida. È la differenza tra una risposta istantanea e un'attesa di minuti. È letteralmente la cosa che, più spesso di ogni altra, trasforma un'applicazione che arranca in una che vola. Quando qualcuno dice il mio database è lento, moltissime volte la vera risposta è: manca un indice sulla cosa che stai cercando di continuo.
Voglio essere onesto sul prezzo, perché nulla è gratis. Se gli indici sono così magici, perché non mettere un indice su tutto? Perché hanno un costo, e va capito. Un indice è una struttura in più da tenere ordinata: ogni volta che scrivi, modifichi o cancelli un dato, Postgres deve aggiornare non solo la tabella, ma anche tutti gli indici collegati. Quindi gli indici rendono le letture velocissime, ma rallentano un po' le scritture, e occupano spazio. Metterne troppi vuol dire pagare quel prezzo su ogni scrittura, per indici che magari non usi mai. La regola sana: indicizza ciò che cerchi spesso, non tutto per sicurezza.
Voglio darti un tocco sul carattere di Postgres, perché qui brilla. Su questo, Postgres è particolarmente ricco. Non ha un solo tipo di indice, ma diversi, ciascuno adatto a una domanda diversa. Ce n'è uno per le ricerche esatte e per gli ordinamenti, uno pensato per cercare dentro i testi lunghi, uno per i dati geografici, per chiedere cosa c'è vicino a questo punto sulla mappa. E, grazie all'estensibilità di cui parleremo, se ne possono aggiungere di nuovi per problemi speciali. La scelta dell'indice giusto per la domanda giusta è parte dell'arte di usare bene Postgres.
Voglio darti l'immagine completa, perché lega tutto. Torniamo al libro. Il testo è la tua tabella. L'indice analitico in fondo è l'indice della base di dati. Aggiungere un capitolo al libro è veloce; ma se vuoi tenere aggiornato anche l'indice analitico, ogni volta che aggiungi contenuto devi anche aggiornare l'indice, ed è lavoro in più. Per questo un libro ha un indice degli argomenti importanti, non uno per ogni singola parola: metteresti troppo lavoro nel tenerli tutti aggiornati, per indici che quasi nessuno userebbe. Stesso identico compromesso, stessa saggezza.
Voglio trarre la lezione generale, perché è una verità ricorrente. La lezione è che quasi sempre, in informatica, si scambia spazio e lavoro di scrittura in cambio di velocità di lettura. L'indice è l'esempio perfetto: paghi un po' di più ogni volta che scrivi, e in cambio trovi le cose infinitamente più in fretta ogni volta che leggi. Siccome quasi tutte le applicazioni leggono molto più di quanto scrivono, è uno scambio quasi sempre vincente, se fatto con criterio. Capire questo scambio, e dove applicarlo, è metà del segreto di una base di dati veloce.
Per oggi ci fermiamo qui. Abbiamo visto gli indici. Senza aiuti, cercare una riga vuol dire leggerle tutte, lentissimo su milioni di righe, come cercare una parola leggendo un libro intero. L'indice è come l'indice analitico in fondo al libro: una struttura ordinata a parte che dice dove sta ogni valore, così Postgres salta dritto alla riga giusta, anche milioni di volte più in fretta. Ma ha un prezzo: ogni scrittura deve aggiornare anche gli indici, e occupano spazio, quindi si indicizza ciò che si cerca spesso, non tutto. Postgres è ricco di tipi di indice diversi per domande diverse. La lezione: si baratta lavoro di scrittura per velocità di lettura, uno scambio quasi sempre vincente. Nella prossima puntata: scrivere l'intenzione prima del fatto. Nelle note trovi qualche spunto. Se ti è utile, condividila. Grazie per l'ascolto, e ci sentiamo alla prossima.