{"id":21331,"date":"2026-09-12T15:01:49","date_gmt":"2026-09-12T13:01:49","guid":{"rendered":"https:\/\/webhosting.de\/mariadb-optimizer-trace-sql-performance-analyse-datenbank\/"},"modified":"2026-09-12T15:01:49","modified_gmt":"2026-09-12T13:01:49","slug":"mariadb-ottimizzatore-tracciamento-analisi-delle-prestazioni-sql-database","status":"publish","type":"post","link":"https:\/\/webhosting.de\/it\/mariadb-optimizer-trace-sql-performance-analyse-datenbank\/","title":{"rendered":"MariaDB Optimizer Trace \u2013 Comprendere nel dettaglio le query SQL"},"content":{"rendered":"<p>Grazie alla traccia dell'ottimizzatore in MariaDB riesco a capire, passo dopo passo, perch\u00e9 l'ottimizzatore sceglie un determinato piano e quali varianti scarta. Questa traccia JSON mi mostra <strong>Decisioni<\/strong> su costi, sequenze di join e filtri, in modo da poter personalizzare le query SQL in modo mirato.<\/p>\n\n<h2>Punti centrali<\/h2>\n\n<ul>\n  <li><strong>Trasparenza<\/strong>: Una traccia basata su JSON illustra le riscritture, i costi e i piani scartati.<\/li>\n  <li><strong>Focus<\/strong>: join_preparation e join_optimization forniscono le informazioni pi\u00f9 importanti.<\/li>\n  <li><strong>Sistema di controllo<\/strong>: Le variabili di sessione riducono il sovraccarico e l'utilizzo della memoria.<\/li>\n  <li><strong>Flusso di lavoro<\/strong>: EXPLAIN\/ANALYZE per il piano, Trace per il \u201eperch\u00e9\u201c.<\/li>\n  <li><strong>Vantaggi pratici<\/strong>: Personalizzare in modo mirato indici, statistiche e sequenze di join.<\/li>\n<\/ul>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img fetchpriority=\"high\" decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/09\/mariadb-optimizer-trace-0294.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Che cos'\u00e8 la traccia dell'ottimizzatore di MariaDB?<\/h2>\n\n<p>A partire dalla versione 10.4, MariaDB implementa un <strong>Ottimizzatore<\/strong> Trace, che documenta in formato JSON ogni fase di ottimizzazione significativa di un\u2019istruzione SELECT, UPDATE o DELETE. In questo modo posso vedere come il motore espanda le query, normalizzi le condizioni e, infine, determini l\u2019ordine dei join, compresi gli accessi agli indici. Questa visione va ben oltre EXPLAIN, che mostra principalmente il piano finale, e rivela le alternative scartate con le relative motivazioni. La traccia \u00e8 presente in memoria per ogni connessione ed \u00e8 disponibile tramite <code>information_schema.OPTIMIZER_TRACE<\/code> pronto. In questo modo ottengo una descrizione completa e leggibile da un computer delle strutture interne <strong>Passi<\/strong>, che hanno portato alla definizione di un piano esecutivo.<\/p>\n\n<h2>Attivare e leggere la traccia dell\u2019ottimizzatore<\/h2>\n\n<p>Attivo questa funzione in modo mirato per ogni sessione, in modo da poter eseguire diagnosi senza un sovraccarico globale e avere il pieno controllo su <strong>Memoria<\/strong> ho. Di solito inserisco <code>SET SESSION optimizer_trace = 'enabled=on';<\/code> e se necessario <code>SET SESSION optimizer_trace_max_mem_size = 1048576;<\/code> o superiore, se la traccia diventa troppo lunga. Dopodich\u00e9 eseguo la query sospetta e leggo la traccia con <code>SELECT * FROM information_schema.OPTIMIZER_TRACE LIMIT 1\\G;<\/code>. Importante: la tabella memorizza solo l\u2019ultima query della connessione attiva, e prendo in considerazione campi come <code>MISSING_BYTES_BEYOND_MAX_MEM_SIZE<\/code> oppure <code>PRIVILEGI INSUFFICIENTI<\/code> per indicazioni diagnostiche. Questo approccio mantiene snello l'ambiente di produzione e rende l'analisi <strong>accurata<\/strong>.<\/p>\n\n<table>\n  <thead>\n    <tr>\n      <th>Variabile\/Campo<\/th>\n      <th>Scopo<\/th>\n      <th>Valore di esempio<\/th>\n    <\/tr>\n  <\/thead>\n  <tbody>\n    <tr>\n      <td><code>optimizer_trace<\/code><\/td>\n      <td>Attiva la traccia per sessione<\/td>\n      <td><code>'enabled=on'<\/code><\/td>\n    <\/tr>\n    <tr>\n      <td><code>optimizer_trace_max_mem_size<\/code><\/td>\n      <td>Memoria massima per traccia<\/td>\n      <td><code>1048576<\/code> (1 MB)<\/td>\n    <\/tr>\n    <tr>\n      <td><code>OPTIMIZER_TRACE.QUERY<\/code><\/td>\n      <td>Istruzione SQL originale<\/td>\n      <td><code>SELECT ...<\/code><\/td>\n    <\/tr>\n    <tr>\n      <td><code>OPTIMIZER_TRACE.TRACE<\/code><\/td>\n      <td>Documento JSON dell'ottimizzazione<\/td>\n      <td>Testo JSON<\/td>\n    <\/tr>\n    <tr>\n      <td><code>MISSING_BYTES_BEYOND_MAX_MEM_SIZE<\/code><\/td>\n      <td>Byte troncati se la traccia \u00e8 troppo lunga<\/td>\n      <td>0 o numero<\/td>\n    <\/tr>\n    <tr>\n      <td><code>PRIVILEGI INSUFFICIENTI<\/code><\/td>\n      <td>\u00c8 sufficiente l'autorizzazione alla lettura?<\/td>\n      <td>0 o 1<\/td>\n    <\/tr>\n  <\/tbody>\n<\/table>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/09\/mariadb_optimizer_besprechung_5829.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Struttura JSON: join_preparation e join_optimization<\/h2>\n\n<p>La struttura JSON \u00e8 suddivisa nei seguenti blocchi <code>join_preparation<\/code> e <code>ottimizzazione delle unioni<\/code>, che esamino per prime perch\u00e9 sono le pi\u00f9 importanti <strong>Note<\/strong> fornire. Nella sezione <code>join_preparation<\/code> riconosco la query estesa (<code>expanded_query<\/code>) e verifico se e in che modo il motore abbia modificato le condizioni o le proiezioni. Il secondo blocco <code>ottimizzazione delle unioni<\/code> registra le stime delle righe, i piani considerati, l\u2019ordine di join scelto e l\u2019aggiunta di parti WHERE selettive alle tabelle. Particolarmente utili sono i sottoalberi <code>rows_estimation<\/code>, <code>piani_di_esecuzione_presunti<\/code> e <code>associare_condizioni_alle_tabelle<\/code>, poich\u00e9 rimandano direttamente alle ipotesi sui costi e alle posizioni dei filtri. In questo modo riesco a individuare rapidamente eventuali valutazioni errate o condizioni sfavorevoli <strong>Indici<\/strong> portare a piani non ottimali.<\/p>\n\n<h2>Ottimizzazione con EXPLAIN e ANALYZE<\/h2>\n\n<p>Per una valutazione completa, combino EXPLAIN, ANALYZE e il <strong>Traccia<\/strong> seguendo una procedura prestabilita. Per prima cosa utilizzo <code>SPIEGARE<\/code> oppure <code>EXPLAIN FORMAT=JSON<\/code>, per visualizzare il piano selezionato e i percorsi chiave. Dopodich\u00e9 imposto <code>SPIEGAZIONE ANALISI<\/code> per ottenere dati reali sui tempi di esecuzione e valori di conteggio come i loop e le righe filtrate. Se rimangono dei dubbi, attivo l\u2019Optimizer Trace e verifico quali varianti l\u2019ottimizzatore ha valutato e scartato. Questo articolo su mi offre una breve introduzione all\u2019interpretazione dei dati <a href=\"https:\/\/webhosting.de\/it\/mysql-explain-analyze-interpretare-le-query-ottimizzazione-delle-query\/\">Comprendere EXPLAIN e ANALYZE<\/a>, a cui ricorro come fonte integrativa quando necessario.<\/p>\n\n<h2>Comprendere le decisioni relative ai piani: costi, cardinalit\u00e0, filtri<\/h2>\n\n<p>La logica decisionale si basa sulle cardinalit\u00e0, sui modelli di costo e sul posizionamento di <strong>Filtro<\/strong> seguendo il piano. Nel trace vedo, per ogni sequenza di join considerata, quali insiemi di righe si aspetta il motore e come ne ricava il costo totale. Verifico se statistiche obsolete o correlazioni sfavorevoli portino a sottovalutare le scansioni di intervallo e a privilegiare le scansioni complete. Inoltre, verifico se il motore applica le condizioni WHERE alla tabella pi\u00f9 selettiva con sufficiente anticipo, in modo da ridurre le costose fasi di join. In questo modo riesco a formulare conclusioni fondate sul motivo per cui \u00e8 stato scelto un determinato piano e su come modificarlo con <strong>Indici<\/strong>, le riscritture o la gestione delle statistiche.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/09\/mariadb-optimizer-trace-sql-4271.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Esempio pratico: tracciamento di una semplice query di filtro<\/h2>\n\n<p>All'indirizzo <code>SELECT * FROM t1 WHERE a &lt; 10<\/code> verifico sotto <code>join_preparation<\/code>, se il motore abbia esteso la proiezione ed eventualmente consolidato le condizioni, il che mi ha dato una prima <strong>Indicatori<\/strong> fornisce. Dopodich\u00e9 vedo nel blocco <code>rows_estimation<\/code>, quante righe il motore utilizza per il range scan su <code>a<\/code> rispetto alla scansione completa della tabella. Se si riscontrano valori non realistici, spesso lo interpreto come un segno di statistiche obsolete o di istogrammi mancanti. Nella sezione <code>piani_di_esecuzione_presunti<\/code> A quel punto capisco se l'accesso all'indice \u00e8 stato effettivamente calcolato come pi\u00f9 conveniente rispetto alla scansione completa. Infine, mostra <code>associare_condizioni_alle_tabelle<\/code>, se la condizione selettiva si applica a <code>a<\/code> \u00e8 in anticipo rispetto al programma, il che riduce notevolmente la durata <strong>si abbassa<\/strong>.<\/p>\n\n<h2>Funzioni JSON: estrarre in modo mirato porzioni di dati<\/h2>\n\n<p>Poich\u00e9 il trace \u00e8 in formato JSON, filtro in modo mirato i sottoalberi con <code>JSON_EXTRACT<\/code> e realizzo piccole analisi per eventi ricorrenti <strong>Campione<\/strong>. Ad esempio, leggo solo l\u2019elenco dei piani presi in considerazione per verificare se determinate sequenze di join falliscono sistematicamente. Allo stesso modo, estraggo i campi relativi ai costi dei candidati principali e li confronto con i dati di ANALYZE per individuare eventuali ipotesi errate. Tramite semplici viste o stored procedure automatizzo questi controlli per le mie sessioni di diagnosi. In questo modo mi costruisco un semplice <strong>Monitoraggio<\/strong> per le decisioni dell'ottimizzatore senza attivare il tracciamento permanente.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/09\/mariadb_optimizer_trace_4729.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Casi d'uso tipici e vantaggi<\/h2>\n\n<p>Ricorro al trace quando EXPLAIN mostra una scansione completa inaspettata e voglio capire il motivo del rifiuto di un <strong>Indice<\/strong> voglio scoprire. Allo stesso modo, per molte tabelle, il trace mi fornisce la motivazione alla base dell'ordine di join scelto, indicandomi la strada verso piani alternativi. In caso di cambio di versione, salvo i trace prima e dopo l\u2019aggiornamento per valutare le modifiche nel comportamento dell\u2019ottimizzatore. Per le questioni strategiche relative al tuning, questa panoramica mi aiuta a <a href=\"https:\/\/webhosting.de\/it\/spiegazione-interna-dellottimizzatore-di-query-di-mariadb-approfondimenti-sullottimizzazione-sql\/\">meccanismi interni dell'ottimizzatore<\/a>, che collego ai risultati di Trace. In questo modo decido in modo strutturato se apportare modifiche agli indici, alle statistiche o alla formulazione delle query <strong>vite di regolazione<\/strong> metto.<\/p>\n\n<h2>Migliori pratiche per la produzione<\/h2>\n\n<p>Attivo sistematicamente la traccia come <strong>Sessione<\/strong>-Chiudo e termino la diagnosi in modo corretto non appena ho raccolto dati sufficienti. Per le tracce di grandi dimensioni, aumento <code>optimizer_trace_max_mem_size<\/code> solo per un breve periodo, dopodich\u00e9 reimpostato il valore su un livello basso. Prima di condividere i file JSON, nascondo le costanti sensibili, i testi dei commenti o gli indicatori aziendali. Utilizzo il trace in modo mirato come strumento di diagnostica, mentre per il monitoraggio continuo preferisco i log delle query lente, le viste sulle prestazioni o i profiler esterni. Questa disciplina mantiene i sistemi snelli e previene inutili <strong>Spese generali<\/strong> nel lavoro quotidiano.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/09\/mariadb_optimizer_trace_3874.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Traccia dell'ottimizzatore nel mix di strumenti<\/h2>\n\n<p>Per un tuning olistico, riproduco la catena costituita dalla comprensione del progetto, dall\u2019analisi delle cause e dalla misurazione del sistema e collego le <strong>Risultati<\/strong>. EXPLAIN mi mostra il piano, ANALYZE conferma i costi effettivi e la traccia fornisce le motivazioni alla base della decisione. Parallelmente, esamino i concetti relativi al piano di esecuzione delle query per individuare schemi nella scelta delle chiavi, nelle cardinalit\u00e0 e nelle strategie di join. Un\u2019ottima integrazione a questa prospettiva \u00e8 la panoramica sintetica su <a href=\"https:\/\/webhosting.de\/it\/piani-di-esecuzione-delle-query-di-database-che-ospitano-informazioni-sulle-prestazioni-di-ottimizzazione\/\">Piani di esecuzione delle query<\/a>, a cui faccio riferimento per le questioni di architettura. Da ci\u00f2 traggo conclusioni attendibili <strong>Priorit\u00e0<\/strong> per il lavoro sull'indice, le riscritture e i parametri.<\/p>\n\n<h2>Approfondimento: analisi della gamma e scelta delle chiavi<\/h2>\n\n<p>Spesso nella traccia c'\u00e8 un blocco <code>analisi_intervallo<\/code> per ogni tabella, in modo da poter individuare quali indici fossero idonei per gli accessi di tipo range, ref o eq-ref. L\u2019ottimizzatore confronta alternative quali \u201erange su idx_a\u201c, \u201erange su idx_b\u201c o \u201efull scan\u201c, assegna loro i costi e il numero di righe previsto e individua l\u2019opzione vincente. Se noto che un indice sensato \u00e8 stato scartato a causa dei costi elevati, esamino successivamente le selettivit\u00e0 e le statistiche sottostanti. Se le ipotesi non sono corrette, un <code>ANALIZZA TABELLA<\/code> (eventualmente con statistiche persistenti) oppure la creazione di un <strong>Indice di copertura<\/strong> annullare la decisione.<\/p>\n\n<p>\u00c8 utile anche esaminare le suddivisioni degli indici composti: la traccia documenta se la condizione utilizza solo la prima colonna dell\u2019indice o se sono applicabili predicati aggiuntivi e se entrano in gioco altre colonne chiave. Da ci\u00f2 deduco se \u00e8 opportuno riformulare i predicati (ad esempio evitando le funzioni) oppure estendere l\u2019indice in modo da coprire i tipici filtri e ordinamenti.<\/p>\n\n<h2>I join in dettaglio: semi-join, BKA\/MRR e buffer di join<\/h2>\n\n<p>Nelle query multi-tabella, le sezioni di traccia indicano se \u00e8 stata presa in considerazione una strategia di semijoin e, in caso affermativo, quale (ad esempio FirstMatch, DuplicateWeedout, LooseScan o Materialization). L\u00ec capisco perch\u00e9 una variante \u00e8 stata scartata \u2013 ad esempio a causa di costi di materializzazione elevati o di una selettivit\u00e0 troppo bassa. Inoltre <strong>Accesso a chiave batch (BKA)<\/strong> e <strong>Lettura multi-campo (MRR)<\/strong> compaiono nella traccia, se attivati. Queste tecniche raggruppano le ricerche delle chiavi e migliorano la localit\u00e0 della cache. Se BKA\/MRR non compaiono nella traccia, controllo <code>optimizer_switch<\/code> e parametri quali <code>join_cache_level<\/code>. Nei carichi di lavoro con numerose ricerche casuali di chiavi, \u00e8 possibile accelerare sensibilmente la fase di join, come si pu\u00f2 verificare con EXPLAIN ANALYZE.<\/p>\n\n<p>\u00c8 inoltre fondamentale considerare la dimensione e il tipo del buffer di join: la traccia mostra se sono state eseguite varianti di Nested Loop con o senza buffer e in quale punto vengono applicati i filtri. Valuto se l\u2019aggiunta di indici sulle chiavi di join o una riscrittura volta a ridurre i risultati intermedi rappresenti una scelta pi\u00f9 efficiente rispetto all\u2019aumento delle dimensioni dei buffer.<\/p>\n\n<h2>Sottoquery, tabelle derivate e viste<\/h2>\n\n<p>All'indirizzo <code>join_preparation<\/code> A mio avviso, se le sottoquery nella forma EXISTS\/IN in <strong>Semijoin<\/strong> sono stati trasformati (<code>in_to_exists<\/code>), se le tabelle derivate sono state unite (<code>derived_merge<\/code>) o siano stati concretizzati e se <strong>Condizione Pushdown<\/strong> fino alle tabelle derivate. Questi passaggi sono fondamentali perch\u00e9 l\u2019assenza di un\u2019operazione di merge pu\u00f2 comportare una materializzazione costosa. Se nel trace noto ripetutamente decisioni di materializzazione con costi elevati, verifico se \u00e8 possibile utilizzare un\u2019operazione esplicita <code>STRAIGHT_JOIN<\/code>, un suggerimento o una riorganizzazione della query (ad es. Common Table Expressions con filtri mirati) induca il motore a adottare una strategia pi\u00f9 efficiente. Nel caso delle viste, verifico se l\u2019ottimizzatore risolva adeguatamente il contenuto della vista o se manchino indici aggiuntivi nella tabella sottostante.<\/p>\n\n<h2>Partizionamento e potatura<\/h2>\n\n<p>Nel caso delle tabelle partizionate, la traccia mostra quali partizioni sono state escluse in base alle chiavi di partizione e ai predicati (<strong>Potatura delle partizioni<\/strong>). Se il pruning previsto non avviene, ci\u00f2 indica che \u00e8 opportuno formulare i filtri in modo pi\u00f9 precoce e in base alla chiave di partizione. Presto inoltre attenzione all\u2019interazione tra partizionamento e indici: in assenza di indici locali o globali, il motore potrebbe controllare un numero eccessivo di righe nonostante il pruning, il che risulta evidente nella traccia a causa degli elevati costi di scansione.<\/p>\n\n<h2>Verificare in modo mirato gli hints, i parametri dell'indice e l'optimizer_switch<\/h2>\n\n<p>Utilizzo il trace per verificare l'effetto degli hint e degli switch dei parametri <strong>occupare<\/strong>. Se, ad esempio, inserisco. <code>FORCE INDEX<\/code> oppure un suggerimento dell'ottimizzatore, nel trace posso vedere se l'alternativa \u00e8 stata effettivamente imposta e come \u00e8 stata valutata. Tramite <code>optimizer_switch<\/code> posso attivare o disattivare temporaneamente le strategie (ad esempio per le decisioni relative a semijoin, index_merge o derived_merge). La traccia mi serve quindi come prova per verificare se il motore ha accettato le specifiche o se continuano a prevalere altre restrizioni (ad esempio le cardinalit\u00e0). Facoltativamente, utilizzo flag di formattazione come <code>one_line<\/code> oppure <code>end_markers<\/code> all'indirizzo <code>optimizer_trace<\/code>-String, per adattare la leggibilit\u00e0 al mio strumento di analisi.<\/p>\n\n<h2>Update\/DELETE e percorsi di scrittura<\/h2>\n\n<p>La traccia dell\u2019ottimizzatore non si limita alle istruzioni SELECT. Anche nel caso delle istruzioni UPDATE e DELETE posso vedere come vengono scelte le vie di accesso e se i filtri vengono applicati con sufficiente anticipo per mantenere basso il numero di righe interessate. Verifico se un filtro WHERE non sia \"sargable\" o se la mancanza di un indice comporti una fase di scansione estesa prima che venga eseguita la modifica effettiva. Dalla traccia deduco se un indice compatto (ad es. solo le colonne necessarie) eviti accessi inutili avanti e indietro, riducendo cos\u00ec i blocchi e il volume del log.<\/p>\n\n<h2>Sicurezza, privilegi e prepared statement<\/h2>\n\n<p>Per poter leggere l'intero record, ho bisogno di privilegi sufficienti sull'oggetto; se questi mancano, il campo segnala <code>PRIVILEGI INSUFFICIENTI<\/code> Limitazioni. In scenari vicini alla produzione utilizzo quindi le stesse credenziali di accesso dell\u2019applicazione o un account di diagnostica con autorizzazioni specifiche. Nel caso delle prepared statement, la traccia mostra in genere gi\u00e0 la forma ottimizzata con i parametri vincolati, il che mi consente di valutare le selettivit\u00e0 senza rivelare costanti sensibili. Se devo condividere le tracce, mascherer\u00f2 i valori dei parametri o li sostituir\u00f2 con intervalli rappresentativi per rispettare i requisiti di protezione dei dati.<\/p>\n\n<h2>Automazione: acquisire, distinguere e documentare le tracce<\/h2>\n\n<p>Per garantire la riproducibilit\u00e0 delle analisi, salvo le tracce in modo casuale in una tabella di diagnostica e le corredo di metadati quali schema, versione, variabili di sessione e data e ora. In questo modo posso confrontare i dati prima e dopo le modifiche agli indici o gli aggiornamenti di versione <strong>diffen<\/strong>, quali decisioni sono state rinviate. \u00c8 utile suddividere i blocchi <code>piani_di_esecuzione_presunti<\/code> e <code>rows_estimation<\/code> da archiviare separatamente, per poter confrontare rapidamente le variazioni dei costi. Alcune piccole query ausiliarie mi consentono di estrarre l'ordine di join selezionato e i costi calcolati \u2013 ad esempio con <code>JSON_EXTRACT(TRACE, '$.join_optimization.considered_execution_plans')<\/code> \u2013 e salvano il risultato insieme ai risultati di EXPLAIN e ANALYZE. In questo modo si ottiene una documentazione affidabile per ogni fase di ottimizzazione.<\/p>\n\n<h2>Limiti, peculiarit\u00e0 delle versioni e confronto con MySQL<\/h2>\n\n<p>Le strutture chiave del trace si basano su MySQL, ma i dettagli e i nomi dei campi possono variare leggermente a seconda della versione di MariaDB. Mi concentro quindi sulla <strong>semantici<\/strong> Sezioni (Rewrites, Rows-Estimation, piani considerati, Condition-Attachments), invece di lasciarmi confondere da differenze puramente estetiche. Importante: in MariaDB l\u2019attenzione \u00e8 focalizzata sull\u2019ultima istruzione della connessione attiva. Chi analizza molte istruzioni consecutive, quindi, le legge immediatamente dopo l\u2019esecuzione o in modo automatizzato tramite hook, in modo che nessuna traccia rilevante venga sovrascritta. Per file JSON molto grandi, tengo conto dello spazio di memoria necessario e comprendo <code>MISSING_BYTES_BEYOND_MAX_MEM_SIZE<\/code> come invito ad aumentare temporaneamente il limite e a ripetere l'analisi.<\/p>\n\n<h2>Estrazioni JSON concrete per l'uso quotidiano<\/h2>\n\n<p>Per concludere, ecco alcuni brevi estratti che utilizzo spesso nella pratica per andare subito al sodo:<\/p>\n\n<ul>\n  <li>Ordine di join selezionato ed elenchi dei candidati: estraggo i prefissi del piano e la tabella ad essi associata per poter ricostruire la sequenza decisionale.<\/li>\n  <li>Alternative di range e costi: estraggo l'elenco degli indici valutati per le tabelle pi\u00f9 selettive, al fine di valutare con precisione le riscritture o i nuovi indici.<\/li>\n  <li>Filtri applicati in fase iniziale: sto leggendo il <code>associare_condizioni_alle_tabelle<\/code>-sezioni, per garantire che i predicati forti siano il pi\u00f9 possibile vicini alla fonte dei dati.<\/li>\n<\/ul>\n\n<p>Grazie alle poche visualizzazioni di queste estrazioni, dispongo di uno strumento di analisi essenziale per le decisioni dell'ottimizzatore, che attivo all'occorrenza durante le sessioni di diagnostica e poi disattivo nuovamente.<\/p>\n\n<h2>Frequenti inciampi e risoluzione di problemi<\/h2>\n\n<p>Se mancano gli istogrammi o le statistiche sono obsolete, le stime risultano errate e generano <strong>Piani<\/strong> con scansioni complete non necessarie. Se nel trace noto cardinalit\u00e0 molto divergenti, aggiorno le statistiche, imposto indici adeguati o riformulo i filtri in modo che possano essere memorizzati in un array. Riconosco i trace troppo succinti tramite <code>MISSING_BYTES_BEYOND_MAX_MEM_SIZE<\/code> e reagisco aumentando temporaneamente il limite. Se ANALYZE fornisce tempi di esecuzione migliori per un percorso alternativo, verifico nella traccia quale fattore di costo abbia favorito la variante scelta. In questo modo colmo passo dopo passo le lacune di conoscenza e raggiungo <strong>Chiarezza<\/strong> sulla logica decisionale.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/09\/mariadb-optimizer-trace-4829.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Riassumendo brevemente<\/h2>\n\n<p>Il MariaDB Optimizer Trace mi spiega, in un documento JSON, come il motore riformuli le query, stimi il numero di righe, confronti i piani e infine generi una <strong>Sequenza<\/strong> seleziona. Lo attivo per ogni sessione, leggo la traccia, controllo <code>join_preparation<\/code> e <code>ottimizzazione delle unioni<\/code> e metto in relazione queste informazioni con EXPLAIN\/ANALYZE. Dai motivi alla base degli indici rifiutati, dei filtri tardivi o delle stime errate deduco misure concrete: indici migliori, statistiche pi\u00f9 aggiornate e formulazioni chiare delle query. Con le funzioni JSON estraggo frammenti, riconosco modelli e documento le decisioni in modo riproducibile. In questo modo riesco a gestire in modo affidabile anche carichi di lavoro SQL di grandi dimensioni. <strong>Prestazioni<\/strong> e rendi comprensibili le decisioni relative alla messa a punto.<\/p>","protected":false},"excerpt":{"rendered":"<p>Scopri come utilizzare MariaDB Optimizer Trace per analizzare e ottimizzare query SQL complesse. Questo articolo spiega come attivare, interpretare e comprendere la struttura JSON dell\u2019Optimizer Trace per migliorare le prestazioni.<\/p>","protected":false},"author":1,"featured_media":21324,"comment_status":"","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[781],"tags":[],"class_list":["post-21331","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-datenbanken-administration-anleitungen"],"acf":[],"_wp_attached_file":null,"_wp_attachment_metadata":null,"litespeed-optimize-size":null,"litespeed-optimize-set":null,"_elementor_source_image_hash":null,"_wp_attachment_image_alt":null,"stockpack_author_name":null,"stockpack_author_url":null,"stockpack_provider":null,"stockpack_image_url":null,"stockpack_license":null,"stockpack_license_url":null,"stockpack_modification":null,"color":null,"original_id":null,"original_url":null,"original_link":null,"unsplash_location":null,"unsplash_sponsor":null,"unsplash_exif":null,"unsplash_attachment_metadata":null,"_elementor_is_screenshot":null,"surfer_file_name":null,"surfer_file_original_url":null,"envato_tk_source_kit":null,"envato_tk_source_index":null,"envato_tk_manifest":null,"envato_tk_folder_name":null,"envato_tk_builder":null,"envato_elements_download_event":null,"_menu_item_type":null,"_menu_item_menu_item_parent":null,"_menu_item_object_id":null,"_menu_item_object":null,"_menu_item_target":null,"_menu_item_classes":null,"_menu_item_xfn":null,"_menu_item_url":null,"_trp_menu_languages":null,"rank_math_primary_category":null,"rank_math_title":null,"inline_featured_image":null,"_yoast_wpseo_primary_category":null,"rank_math_schema_blogposting":null,"rank_math_schema_videoobject":null,"_oembed_049c719bc4a9f89deaead66a7da9fddc":null,"_oembed_time_049c719bc4a9f89deaead66a7da9fddc":null,"_yoast_wpseo_focuskw":null,"_yoast_wpseo_linkdex":null,"_oembed_27e3473bf8bec795fbeb3a9d38489348":null,"_oembed_c3b0f6959478faf92a1f343d8f96b19e":null,"_trp_translated_slug_en_us":null,"_wp_desired_post_slug":null,"_yoast_wpseo_title":null,"tldname":null,"tldpreis":null,"tldrubrik":null,"tldpolicylink":null,"tldsize":null,"tldregistrierungsdauer":null,"tldtransfer":null,"tldwhoisprivacy":null,"tldregistrarchange":null,"tldregistrantchange":null,"tldwhoisupdate":null,"tldnameserverupdate":null,"tlddeletesofort":null,"tlddeleteexpire":null,"tldumlaute":null,"tldrestore":null,"tldsubcategory":null,"tldbildname":null,"tldbildurl":null,"tldclean":null,"tldcategory":null,"tldpolicy":null,"tldbesonderheiten":null,"tld_bedeutung":null,"_oembed_d167040d816d8f94c072940c8009f5f8":null,"_oembed_b0a0fa59ef14f8870da2c63f2027d064":null,"_oembed_4792fa4dfb2a8f09ab950a73b7f313ba":null,"_oembed_33ceb1fe54a8ab775d9410abf699878d":null,"_oembed_fd7014d14d919b45ec004937c0db9335":null,"_oembed_21a029d076783ec3e8042698c351bd7e":null,"_oembed_be5ea8a0c7b18e658f08cc571a909452":null,"_oembed_a9ca7a298b19f9b48ec5914e010294d2":null,"_oembed_f8db6b27d08a2bb1f920e7647808899a":null,"_oembed_168ebde5096e77d8a89326519af9e022":null,"_oembed_cdb76f1b345b42743edfe25481b6f98f":null,"_oembed_87b0613611ae54e86e8864265404b0a1":null,"_oembed_27aa0e5cf3f1bb4bc416a4641a5ac273":null,"_oembed_time_27aa0e5cf3f1bb4bc416a4641a5ac273":null,"_tldname":null,"_tldclean":null,"_tldpreis":null,"_tldcategory":null,"_tldsubcategory":null,"_tldpolicy":null,"_tldpolicylink":null,"_tldsize":null,"_tldregistrierungsdauer":null,"_tldtransfer":null,"_tldwhoisprivacy":null,"_tldregistrarchange":null,"_tldregistrantchange":null,"_tldwhoisupdate":null,"_tldnameserverupdate":null,"_tlddeletesofort":null,"_tlddeleteexpire":null,"_tldumlaute":null,"_tldrestore":null,"_tldbildname":null,"_tldbildurl":null,"_tld_bedeutung":null,"_tldbesonderheiten":null,"_oembed_ad96e4112edb9f8ffa35731d4098bc6b":null,"_oembed_8357e2b8a2575c74ed5978f262a10126":null,"_oembed_3d5fea5103dd0d22ec5d6a33eff7f863":null,"_eael_widget_elements":null,"_oembed_0d8a206f09633e3d62b95a15a4dd0487":null,"_oembed_time_0d8a206f09633e3d62b95a15a4dd0487":null,"_aioseo_description":null,"_eb_attr":null,"_eb_data_table":null,"_oembed_819a879e7da16dd629cfd15a97334c8a":null,"_oembed_time_819a879e7da16dd629cfd15a97334c8a":null,"_acf_changed":null,"_wpcode_auto_insert":null,"_edit_last":null,"_edit_lock":null,"_oembed_e7b913c6c84084ed9702cb4feb012ddd":null,"_oembed_bfde9e10f59a17b85fc8917fa7edf782":null,"_oembed_time_bfde9e10f59a17b85fc8917fa7edf782":null,"_oembed_03514b67990db061d7c4672de26dc514":null,"_oembed_time_03514b67990db061d7c4672de26dc514":null,"rank_math_news_sitemap_robots":null,"rank_math_robots":null,"_eael_post_view_count":"62","_trp_automatically_translated_slug_ru_ru":null,"_trp_automatically_translated_slug_et":null,"_trp_automatically_translated_slug_lv":null,"_trp_automatically_translated_slug_fr_fr":null,"_trp_automatically_translated_slug_en_us":null,"_wp_old_slug":null,"_trp_automatically_translated_slug_da_dk":null,"_trp_automatically_translated_slug_pl_pl":null,"_trp_automatically_translated_slug_es_es":null,"_trp_automatically_translated_slug_hu_hu":null,"_trp_automatically_translated_slug_fi":null,"_trp_automatically_translated_slug_ja":null,"_trp_automatically_translated_slug_lt_lt":null,"_elementor_edit_mode":null,"_elementor_template_type":null,"_elementor_version":null,"_elementor_pro_version":null,"_wp_page_template":null,"_elementor_page_settings":null,"_elementor_data":null,"_elementor_css":null,"_elementor_conditions":null,"_happyaddons_elements_cache":null,"_oembed_75446120c39305f0da0ccd147f6de9cb":null,"_oembed_time_75446120c39305f0da0ccd147f6de9cb":null,"_oembed_3efb2c3e76a18143e7207993a2a6939a":null,"_oembed_time_3efb2c3e76a18143e7207993a2a6939a":null,"_oembed_59808117857ddf57e478a31d79f76e4d":null,"_oembed_time_59808117857ddf57e478a31d79f76e4d":null,"_oembed_965c5b49aa8d22ce37dfb3bde0268600":null,"_oembed_time_965c5b49aa8d22ce37dfb3bde0268600":null,"_oembed_81002f7ee3604f645db4ebcfd1912acf":null,"_oembed_time_81002f7ee3604f645db4ebcfd1912acf":null,"_elementor_screenshot":null,"_oembed_7ea3429961cf98fa85da9747683af827":null,"_oembed_time_7ea3429961cf98fa85da9747683af827":null,"_elementor_controls_usage":null,"_elementor_page_assets":[],"_elementor_screenshot_failed":null,"theplus_transient_widgets":null,"_eael_custom_js":null,"_wp_old_date":null,"_trp_automatically_translated_slug_it_it":null,"_trp_automatically_translated_slug_pt_pt":null,"_trp_automatically_translated_slug_zh_cn":null,"_trp_automatically_translated_slug_nl_nl":null,"_trp_automatically_translated_slug_pt_br":null,"_trp_automatically_translated_slug_sv_se":null,"rank_math_analytic_object_id":null,"rank_math_internal_links_processed":"1","_trp_automatically_translated_slug_ro_ro":null,"_trp_automatically_translated_slug_sk_sk":null,"_trp_automatically_translated_slug_bg_bg":null,"_trp_automatically_translated_slug_sl_si":null,"litespeed_vpi_list":null,"litespeed_vpi_list_mobile":null,"rank_math_seo_score":null,"rank_math_contentai_score":null,"ilj_limitincominglinks":null,"ilj_maxincominglinks":null,"ilj_limitoutgoinglinks":null,"ilj_maxoutgoinglinks":null,"ilj_limitlinksperparagraph":null,"ilj_linksperparagraph":null,"ilj_blacklistdefinition":null,"ilj_linkdefinition":null,"_eb_reusable_block_ids":null,"rank_math_focus_keyword":"optimizer trace","rank_math_og_content_image":null,"_yoast_wpseo_metadesc":null,"_yoast_wpseo_content_score":null,"_yoast_wpseo_focuskeywords":null,"_yoast_wpseo_keywordsynonyms":null,"_yoast_wpseo_estimated-reading-time-minutes":null,"rank_math_description":null,"surfer_last_post_update":null,"surfer_last_post_update_direction":null,"surfer_keywords":null,"surfer_location":null,"surfer_draft_id":null,"surfer_permalink_hash":null,"surfer_scrape_ready":null,"_thumbnail_id":"21324","footnotes":null,"_links":{"self":[{"href":"https:\/\/webhosting.de\/it\/wp-json\/wp\/v2\/posts\/21331","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/webhosting.de\/it\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/webhosting.de\/it\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/webhosting.de\/it\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/webhosting.de\/it\/wp-json\/wp\/v2\/comments?post=21331"}],"version-history":[{"count":0,"href":"https:\/\/webhosting.de\/it\/wp-json\/wp\/v2\/posts\/21331\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/webhosting.de\/it\/wp-json\/wp\/v2\/media\/21324"}],"wp:attachment":[{"href":"https:\/\/webhosting.de\/it\/wp-json\/wp\/v2\/media?parent=21331"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/webhosting.de\/it\/wp-json\/wp\/v2\/categories?post=21331"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/webhosting.de\/it\/wp-json\/wp\/v2\/tags?post=21331"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}