Che cos'è una query sul database?

Aggiornato: ottobre 2026

Una query sul database è una richiesta strutturata di dati – filtrare, ordinare, proiettare, paginare – scritta in un linguaggio che il motore esegue. L’idea profonda sotto ogni linguaggio di query è la dichiaratività: si descrive il risultato, e il motore sceglie il percorso. Basta padroneggiare una volta i cinque verbi e il modello di costo, e ogni sintassi – SQL, API documentali, GraphQL, builder degli SDK – diventa un accento, non una lingua nuova.

Punti chiave

DomandaRisposta
Che cos’èUna richiesta precisa: quali record, in che ordine, quali campi, quanti
Il paradigmaDichiarativo – si dice che cosa; l’ottimizzatore decide come
La pipelineAnalisi → validazione → pianificazione/ottimizzazione → esecuzione
Il modello di costoRicerca tramite indice vs. scansione completa – EXPLAIN dice quale dei due
La regola di sicurezzaParametrizzare sempre; mai concatenare un input dentro una query

La stessa query in quattro linguaggi di query

La stessa richiesta – articoli pubblicati, oltre 1.000 visualizzazioni, dal più recente – attraverso le famiglie di linguaggi:

-- SQL: il dichiarativo originale
SELECT title, views FROM articles
WHERE  status = 'published' AND views > 1000
ORDER  BY published_at DESC
LIMIT  20;
// API di query documentale
db.articles.find(
  { status: 'published', views: { $gt: 1000 } },  // filtrare
  { title: 1, views: 1 }                          // proiettare
).sort({ publishedAt: -1 }).limit(20)

// GraphQL: i client dichiarano la forma che vogliono ricevere
query {
  articles(where: { status: "published", views_gt: 1000 },
           orderBy: publishedAt_DESC, first: 20) {
    title
    views
  }
}

E il builder dell’SDK – la superficie che il codice applicativo usa davvero, compilata nella stessa anatomia:

// JavaScript / Node.js — Back4app JS SDK
// Filter, sort, project, paginate — the full anatomy in one query
const query = new Parse.Query('Article');
query.equalTo('status', 'published');       // filter
query.greaterThan('views', 1000);           // filter (range)
query.descending('publishedAt');            // sort
query.select('title', 'views');             // project: only these fields
query.limit(20).skip(40);                   // paginate: page 3
const articles = await query.find();

Come un database esegue una query

Pipeline di esecuzione di una queryIl motore analizza il testo della query per ricavarne un albero sintattico, lo valida rispetto allo schema, pianifica e ottimizza scegliendo indici e strategie di join in base al costo, poi esegue il piano e restituisce i risultati.

Testo della query

Analisi
albero sintattico

Validazione
rispetto allo schema

Pianificazione e ottimizzazione
indici · ordine dei join · costo

Esecuzione
risultati in streaming

Il motore analizza il testo della query per ricavarne un albero sintattico, lo valida rispetto allo schema, pianifica e ottimizza scegliendo indici e strategie di join in base al costo, poi esegue il piano e restituisce i risultati.

L’ottimizzatore è la ragione per cui le query dichiarative funzionano: pesa gli indici disponibili, stima il numero di righe e sceglie il piano meno costoso – e EXPLAIN ne mostra la decisione. Il metodo di performance in una riga: lanciare EXPLAIN, cercare la scansione completa, aggiungere l’indice che il filtro sta implorando, guardare di nuovo.

Dichiarativo vs. imperativo

DimensioneQuery dichiarativaCodice imperativo
Che cosa si scriveIl risultato desideratoI passi per calcolarlo
Chi ottimizzaIl motore, a ogni esecuzioneChi scrive il codice, una volta sola
Si adatta al volume dei datiSì – i piani cambiano con le statisticheNo – il ciclo resta il ciclo
Dove viveSQL, API documentali, GraphQL, builderCicli applicativi sui record
Sintomo di fallimentoPiano sbagliato (si corregge con indici/hint)Cicli N+1, esplosioni di memoria

L’anatomia che si ritrova in tutti: filtrare (WHERE), ordinare (ORDER BY), proiettare (la lista del SELECT – chiedere solo ciò che serve), paginare (LIMIT più offset o cursore), aggregare (GROUP BY e affini). Cinque verbi, tutte le superfici.

Le due regole che evitano la maggior parte degli incidenti da query

Parametrizzare, sempre. L’injection è un input ostile che diventa struttura della query – un problema risolto del tutto da segnaposto che associano l’input come valore:

// Vulnerabile: input concatenato nella struttura della query
db.query(`SELECT * FROM users WHERE name = '${input}'`);   // mai così

// Sicuro: parametrizzato – l'input è un dato, non sintassi
db.query('SELECT * FROM users WHERE name = $1', [input]);

I builder degli SDK e le variabili GraphQL lo fanno per costruzione – una delle vittorie silenziose, in termini di sicurezza, delle superfici di query di livello più alto.

Paginare secondo la forma dell’accesso. La paginazione per offset (LIMIT 20 OFFSET 400) permette di arrivare a qualunque pagina, ma paga la profondità in modo lineare e vacilla sotto le scritture concorrenti; la paginazione per cursore (WHERE published_at < $last) è stabile e a costo costante a qualunque profondità, ma avanza solo in un senso. Feed e scroll infinito vogliono i cursori; le tabelle di amministrazione numerate per pagina sono il terreno legittimo dell’offset.

Casi d’uso tipici

  • Letture applicative. Viste a elenco, schermate di dettaglio, ricerca – il quartetto filtra-ordina-proietta-pagina nel suo habitat naturale.
  • Aggregazione e reporting. Conteggi, somme, sintesi raggruppate – spinti nel motore, dove stanno i dati, invece di essere calcolati nel codice applicativo.
  • Superfici di API. Le API generate automaticamente traducono parametri di URL o selezioni GraphQL in queste stesse query – l’anatomia traspare attraverso ogni astrazione.
  • Filtri in tempo reale. Le sottoscrizioni live sono query permanenti – gli stessi predicati, valutati di continuo.
  • Fare debug in produzione. EXPLAIN più il log delle query lente è il ciclo di diagnosi per la categoria di incidenti “è diventato lento”.

Linguaggio nativo, builder o SDK? Matrice decisionale

Scegliere…Quando…Attenzione a…
Il linguaggio di query nativoAggregazioni complesse, report, migrazioniL’injection in caso di concatenazione; la portabilità
Un query builder / SDKCRUD applicativo ed elenchi – quasi tutto il codiceI cicli N+1; i builder nascondono il piano
GraphQLI client devono scegliere i campi e annidare le relazioniUn costo di query non limitato in assenza di tetti
Logica memorizzata / lato serverOperazioni a più passi vicino ai datiLogica nascosta fuori dalla codebase

La regola onesta della discussione sui livelli di astrazione vale parola per parola: builder per il 90 % di routine, query native dove il controllo si ripaga – e la conoscenza dell’anatomia si trasferisce in entrambi i casi.

Limiti e trade-off

  • Il dichiarativo non è gratuito. L’ottimizzatore vale quanto valgono le sue statistiche e i suoi indici; una query giusta su indici sbagliati resta lenta.
  • Le query nascondono il proprio costo. Una riga di catena del builder può essere una scansione su milioni di righe; EXPLAIN è l’unico specchio onesto.
  • La trappola N+1 vive sopra la query. Query singole perfette, emesse dentro un ciclo, sono collettivamente patologiche – il batching e gli include esistono per questo.
  • La paginazione profonda degrada. La profondità dell’offset ha costo lineare; conviene progettare i feed intorno ai cursori dal primo giorno.
  • La proliferazione dei linguaggi è reale. SQL, API documentali, GraphQL, DSL di ricerca – ogni superficie costa una tassa al team; l’anatomia condivisa è l’antidoto.

Le query 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. Il suo approccio alle query è la via del builder dell’SDK portata fino in fondo: il query builder di ogni SDK – i tab di codice qui sopra – compila filtrare, ordinare, proiettare e paginare in query parametrizzate senza superficie di injection, include() gestisce le relazioni senza cicli N+1, gli stessi predicati alimentano le live queries per gli aggiornamenti in tempo reale, e GraphQL serve i client che vogliono dichiarare la propria forma. Cinque verbi, tutte le superfici, un solo backend.

Domande frequenti

Che cos'è una query sul database in parole semplici?

Una richiesta strutturata che chiede al database di recuperare o modificare dati – "dammi gli articoli pubblicati con più di mille visualizzazioni, dal più recente, venti alla volta". Si scrive in un linguaggio di query oppure si costruisce con un SDK, segue una sintassi rigorosa perché il motore possa analizzarla e restituisce esattamente la porzione di dati che descrive.

SQL è dichiarativo o imperativo?

Dichiarativo – si dichiara quali dati servono, e l'ottimizzatore del motore decide come recuperarli: quali indici usare, quale ordine dei join, quale algoritmo. Quella divisione del lavoro è l'idea centrale delle query moderne, e vale oltre SQL: anche le API di query documentali e GraphQL sono dichiarative. Il codice imperativo cicla sui record; le query dichiarative descrivono i risultati.

Come viene eseguita davvero una query?

Una pipeline in quattro fasi: il motore analizza il testo e ne ricava un albero sintattico, lo valida rispetto allo schema, pianifica e ottimizza – scegliendo indici, ordine dei join e algoritmi per costo stimato – poi esegue il piano scelto e restituisce i risultati in streaming. Il piano è ispezionabile: EXPLAIN mostra esattamente ciò che ha deciso l'ottimizzatore, ed è da lì che parte ogni debug delle prestazioni.

Qual è l'anatomia di una query?

Cinque verbi coprono quasi tutto: filtrare (quali record – WHERE), ordinare (in che ordine – ORDER BY), proiettare (quali campi – la lista del SELECT), paginare (quanti, da dove – LIMIT/OFFSET oppure un cursore) e aggregare (sintesi calcolate – GROUP BY). Ogni linguaggio di query e ogni SDK esprime questi stessi cinque verbi; cambia solo la sintassi.

Come rendono rapide le query gli indici?

Sostituiscono la scansione con la ricerca: invece di leggere ogni record per trovare le corrispondenze (costo lineare nella dimensione della tabella), il motore percorre una struttura ordinata fino a esse (costo logaritmico). La differenza è invisibile su mille righe ed è decisiva su dieci milioni. EXPLAIN rivela quale dei due comportamenti si sta ottenendo – una scansione sequenziale su una tabella grande è il classico campanello d'allarme.

Che cos'è la SQL injection e come la prevengono le query parametrizzate?

L'injection è un input ostile che cambia la struttura di una query – i classici trucchi con apici e commenti che trasformano un controllo di accesso in una tautologia. Le query parametrizzate chiudono il buco separando il codice dai dati: il testo della query contiene segnaposto, i valori vengono associati a parte e l'input viene trattato sempre e solo come valore, mai analizzato come sintassi. SDK e query builder parametrizzano per costruzione.

Qual è la differenza tra paginazione per offset e per cursore?

La paginazione per offset (salta N, prendi 20) è semplice e permette di arrivare a qualunque pagina, ma il motore deve contare e scartare le righe saltate – la pagina 500 costa più della pagina 1 – e le scritture concorrenti possono spostare i risultati tra le pagine. La paginazione per cursore ("dopo questa chiave, prendi 20") resta rapida e stabile a qualunque profondità, al prezzo di non poter saltare a una pagina arbitraria. I feed vogliono i cursori; per le piccole tabelle di amministrazione l'offset va benissimo.

Gli SDK e i query builder sostituiscono la conoscenza delle query?

Sostituiscono la scrittura della sintassi, non la comprensione della semantica. Una catena di builder compila nella stessa anatomia filtra-ordina-proietta-pagina e sfrutta gli stessi indici – oppure li manca. Il fallimento classico è il pattern N+1: una query per elemento dentro un ciclo, invisibile nel codice e brutale in produzione. L'anatomia e il modello di costo si trasferiscono a ogni superficie.

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-09