Quali query rallentano una rotta Drupal, e come le isoli in produzione

Approfondisci il progetto Native Observability
Il database registra le query lente ma non sa da quale pagina arrivino, e un profiler di sviluppo non era acceso quando quella pagina era lenta. Native Observability è un modulo Drupal che scrive le due informazioni insieme mentre la richiesta è ancora in corso: per ogni query oltre una soglia salva una riga con la query e la pagina che l'ha eseguita. Le righe si leggono dall'area di amministrazione, e un controllo dice se quello che vedi è completo o se ne è stata scartata qualcuna.

Quale query rallenta una pagina Drupal, e come si scopre?

Si scopre solo se qualcosa ha scritto il nome della pagina accanto alla query mentre la richiesta era in corso. Dopo non si ricostruisce più: il database conserva le query lente, ma per lui sono istruzioni arrivate da una connessione, non pagine di un sito.

Native Observability è un modulo Drupal che registra dall'interno che cosa succede a ogni richiesta. Il suo sottomodulo Database Observer fa una cosa sola: quando una query supera una soglia di durata, salva una riga con due informazioni accostate, la query e la pagina che l'ha eseguita.

Questa pagina racconta tre cose: che cosa ci si trova dentro quella riga, quanto ci si può fidare di quello che si legge, e da dove si comincia. Quanto rallenta il sito tenere acceso il modulo è un'altra domanda, e la risposta è misurata nell'articolo dedicato al suo costo. Lo stesso problema, per le chiamate HTTP verso servizi esterni, è nell'articolo sul servizio esterno che rallenta una rotta.

Perché gli strumenti che hai già non rispondono

Rispondono a domande vicine, e nessuna è questa.

Il log lento di MySQL conosce le query e ignora le pagine. Non è un limite di configurazione, è la sua definizione: il manuale lo descrive come l'elenco delle istruzioni SQL che superano una certa durata. Istruzioni, non pagine. I campi che salva sono quelli del database, cioè durata, righe lette e righe restituite, e nessuno di questi dice da dove sia partita la richiesta: il database riceve comandi da una connessione e non sa che sopra di lui esista un sito. Alla fine hai la query colpevole e vai a cercarla a mano dentro il codice.

Gli strumenti di sviluppo guardano la pagina che hai aperto adesso, non quella lenta di ieri che non riesci a riprodurre.

Strumento A quale domanda risponde
Devel quali query sta eseguendo la pagina che sto guardando ora
WebProfiler quanto tempo e quante query ha speso la pagina che sto guardando ora
XHProf in quali funzioni se ne va il tempo, e chi chiama chi
DB Performance quali query sono lente sul sito, raggruppate per forma della query
Native Observability quali query hanno rallentato una certa pagina, anche ieri, anche mentre non la guardavo

Due precisazioni, perché girano capovolte. La prima: Devel dichiara di essere sicuro in produzione, alla lettera, sulla sua pagina di progetto, a patto di dare il permesso giusto solo a chi sviluppa. Il confine quindi non è fra sviluppo e produzione: è fra la richiesta che stai facendo tu e la storia delle richieste degli altri. La seconda: XHProf scende in un dettaglio che qui non troverai, perché ricostruisce l'albero delle chiamate, mentre Native Observability cronometra i servizi e si ferma lì.

DB Performance è quello che arriva più vicino, e la differenza è netta: raggruppa le query lente per forma e suggerisce indici, ma sulla sua pagina di progetto non compare mai la parola rotta né la parola URL. Nessuno di questi strumenti scrive da quale pagina la query sia arrivata.

Che cosa si vede, quando il collegamento c'è

Una riga per ogni query lenta, e niente per le altre.

In un ambiente di misura con Drupal 11, con le impostazioni predefinite del modulo, una pagina costruita per essere lenta risponde in circa 0,6 secondi. In tabella resta questo:

route_name        testing_native_observability.probe_slow_db
duration_ms       603.968
query_text        SELECT SLEEP(:s)
query_hash        0f907bc4...

Quattro informazioni, e servono tutte:

  • la rotta è il nome che Drupal dà a una pagina dal punto di vista del codice. Dice quale parte del sito ha generato la query, anche quando l'indirizzo cambia a ogni visita;
  • la durata è in millisecondi, quindi circa 0,6 secondi;
  • il testo della query è, accanto, la classe e il metodo che l'hanno eseguita;
  • l'impronta è un codice calcolato sul testo SQL ripulito dai valori. Serve a ritrovare la stessa query su altre pagine e in altri giorni, anche quando i valori cambiano.

Nella stessa richiesta girava anche una seconda query pesante, e non compare. È durata meno della soglia predefinita di cento millisecondi, quindi non è stata salvata. La soglia si comporta da cancello, non da registratore.

Le stesse righe si leggono a video su /admin/reports/native-observability/database-observer, con il permesso access native observability database observer.

Quanto ti puoi fidare di quella tabella

Dipende da due impostazioni, e la seconda merita attenzione.

La prima è la soglia, cento millisecondi di default: decide quanto deve durare una query per finire in tabella. Abbassarla non porta più verità, porta più righe, e sotto qualche millisecondo stai registrando il funzionamento normale del sito.

La seconda è il massimo di righe per richiesta, venti di default. Se una pagina produce più di venti query lente, le altre vengono scartate, e per ora nessuna schermata te lo dice. Venti righe in tabella sono indistinguibili da venti query lente davvero avvenute.

C'è però un modo di accorgersene, perché il modulo salva anche quante query lente ha visto, prima di scartarne qualcuna. Questa query mette in fila le richieste in cui è successo, confrontando le righe salvate (stored_rows) con quelle viste (slow_queries_seen):

SELECT request_id, route_name, COUNT(*) AS stored_rows,
       MAX(JSON_EXTRACT(payload, '$.request_summary.slow_query_count')) AS slow_queries_seen
FROM native_observability_database_query
GROUP BY request_id, route_name
HAVING slow_queries_seen > stored_rows;

Nell'ambiente di misura il taglio si vede a occhio nudo: una pagina che esegue venticinque query lente lascia in tabella esattamente venti righe, e le cinque in più non esistono da nessuna parte.

Un'ultima cosa, per non cercarle altrove: il Database Observer non scrive niente nel log di Drupal. Quello che ha visto sta nella sua tabella e nel suo report, e in nessun altro posto.

Se la pagina lenta la chiama un altro sistema

Il collegamento si mantiene con due intestazioni HTTP. Chi chiama mette il proprio identificativo in X-Native-Observability-Parent-Request-Id, Drupal risponde con X-Native-Observability-Request-Id, e il modulo conserva il legame fra le due richieste. Da lì si arriva alle query lente di quella pagina.

Una avvertenza per non restare delusi: verso un dominio diverso dal tuo, l'identificativo lo deve mettere chi chiama. Il modulo lo aggiunge da solo solo alle chiamate che restano sullo stesso sito.

Da dove si comincia

Quattro passi, e dopo il primo la tabella comincia a riempirsi.

  1. Installa il sottomodulo: drush en native_observability_database_observer -y. Si porta dietro il modulo principale.
  2. Dai il permesso access native observability database observer a chi deve leggere il report, e administer native observability database observer a chi deve cambiarne le impostazioni.
  3. Lascia la soglia a cento millisecondi per qualche giorno, poi guarda il report. Se la tabella resta vuota, sulle pagine che stai guardando non ci sono query lente: è un risultato, non un guasto.
  4. Prima di trarre conclusioni, fai girare la query di controllo qui sopra. Se restituisce righe, stai leggendo solo una parte di quello che è successo.

Che cosa questa prova non dimostra

La lentezza dell'ambiente di misura è finta, ed è giusto saperlo.

  • Il ritardo è iniettato da una pagina di test. La prova mostra il meccanismo, non che il modulo sappia diagnosticare da solo una lentezza vera, che di solito nasce da un indice mancante o da una query ripetuta dentro un ciclo.
  • Per mostrare il taglio delle righe la soglia è stata abbassata di proposito. Il caso in cui sia la lentezza vera a produrre più di venti query lente in una sola richiesta non è stato riprodotto.
  • Nessuna concorrenza e nessuna correzione rimisurata: una richiesta alla volta, su una pagina lenta per costruzione. I tempi assoluti non vanno letti come misura di prestazioni.

Fonti e riferimenti

Tutte le fonti sono state consultate il 27 settembre 2026.

  1. The Slow Query Log, MySQL 8.4 Reference Manual (si apre in una nuova scheda). Definizione del log lento e campi scritti. Letta dal DOM reso: a curl il sito risponde 403.
  2. Devel, pagina di progetto (si apre in una nuova scheda). La frase sulla sicurezza in produzione e il permesso da concedere. Letta dal DOM reso.
  3. WebProfiler, pagina di progetto (si apre in una nuova scheda). La toolbar in fondo a ogni pagina. Letta dal DOM reso.
  4. XHProf, pagina di progetto (si apre in una nuova scheda). Profiler gerarchico, scomposizione per chiamanti e chiamati. Letta dal DOM reso.
  5. DB Performance, pagina di progetto (si apre in una nuova scheda). Aggregazione per forma della query e suggerimento di indici, release 1.0.0-alpha2. Letta dal DOM reso.
  6. Native Observability, pagina di progetto (si apre in una nuova scheda). Requisiti e sottomoduli.
  7. Sorgente del modulo, ramo 2.0.x (si apre in una nuova scheda). Le classi citate in questa pagina si aprono da lì: DatabaseQueryObserverSubscriber per il conteggio delle query lente prima del limite per richiesta, DatabaseObserverSettingsForm per i vincoli delle due impostazioni, TraceSubscriber per le due intestazioni HTTP.
  8. I numeri di questa pagina vengono da un ambiente di misura con Drupal 11 che ho costruito io, non da un sito pubblico: comandi e risultati sono riprodotti qui sopra per intero, e le condizioni in cui valgono stanno nella sezione «Che cosa questa prova non dimostra». Non è una fonte che puoi aprire, è una misura che puoi rifare.
Giorgio Alfredo Pagano
Modificato dall'AI

Questo contenuto è stato prodotto dall'AI e rivisto da una persona.

Come è stata usata l'AI?

Le bozze sono prodotte con l'assistenza dell'AI, poi dirette, rivedute e verificate da una persona. Numeri, date e versioni sono confrontati con le fonti pubbliche prima della pubblicazione, e la data di quel controllo è indicata nel testo.