×
Home > Blog > Le cause più comuni di rallentamento e perdita di performance per applicazioni web sviluppate in PHP/Mysql

Le cause più comuni di rallentamento e perdita di performance per applicazioni web sviluppate in PHP/Mysql

scritto martedì 10 Settembre 2024

Le cause di rallentamento sono piuttosto comuni e significative in molte applicazioni web basate su PHP e MySQL. Ecco un'analisi più dettagliata di ciascuna di esse e alcune soluzioni specifiche per affrontarle:


1. Query non ottimizzate che usano FILESORT senza indici


Quando MySQL utilizza FILESORT, sta essenzialmente ordinando i risultati di una query in memoria (e potenzialmente su disco se la memoria non è sufficiente), il che può rallentare drasticamente le operazioni, specialmente per tabelle grandi. Questo succede spesso quando mancano gli indici adeguati su colonne utilizzate in clausole ORDER BYGROUP BY, o WHERE.


Soluzioni:



  • Aggiunta di indici appropriati: assicurati che le colonne utilizzate in ORDER BYGROUP BY e WHERE abbiano indici adeguati. L'uso di indici composti può migliorare ulteriormente le prestazioni quando vengono usate più colonne in queste clausole.

  • Usa EXPLAIN per il profiling delle query: utilizza EXPLAIN per identificare dove vengono utilizzati FILESORT o TEMPORARY. Se una query mostra questi avvertimenti, considera di riprogettarla.

  • Ottimizzazione della query: rivedi la struttura della query e verifica se puoi ridurre o eliminare l'ordinamento a livello di query. Talvolta, ordinamenti complessi possono essere gestiti in memoria dall'applicazione PHP se la quantità di dati è gestibile.


2. Query innestate (query fatte dentro a un ciclo)


Eseguire query SQL all'interno di un ciclo è un problema molto comune e può causare gravi rallentamenti, specialmente quando il ciclo è grande. Questo avviene perché ogni iterazione del ciclo potrebbe causare una nuova connessione al database e un'operazione SQL, il che può portare a migliaia di query per una singola richiesta.


Soluzioni:



  • Ristrutturazione delle query: se possibile, cerca di spostare le query fuori dai cicli e ristrutturare il codice in modo da eseguire una singola query più complessa che restituisca tutti i dati necessari. Ad esempio, se stai estraendo dati correlati, utilizza JOIN o IN piuttosto che eseguire una query per ogni elemento del ciclo.

  • Pre-fetching dei dati: puoi eseguire una query più grande prima del ciclo per recuperare tutti i dati necessari e poi elaborare i risultati in PHP. Questo riduce il numero di interazioni con il database.

  • Caching dei risultati: se una query è eseguita ripetutamente con gli stessi parametri, considera di memorizzare in cache i risultati per ridurre il numero di chiamate al database.


3. Collegamenti a filesystem esterni (per esempio FTP, Samba) che rispondono lentamente o non rispondono affatto


I collegamenti a filesystem esterni come server FTP o Samba possono causare rallentamenti significativi se questi rispondono lentamente o non rispondono affatto. Questo problema è particolarmente rilevante quando l'applicazione PHP deve accedere frequentemente a risorse esterne come file o directory su questi sistemi.


Soluzioni:



  • Caching dei dati: memorizza in cache i dati recuperati dai filesystem esterni per ridurre la frequenza di accesso a queste risorse. Questo può essere fatto in memoria o su disco locale.

  • Timeout e gestione degli errori: imposta timeout adeguati e gestisci gli errori in modo che l'applicazione possa recuperare o continuare senza bloccare l'intero processo se un filesystem esterno non risponde.

  • Asincronia nelle operazioni su filesystem esterni: se possibile, esegui operazioni asincrone quando interagisci con filesystem esterni. Ciò consente all'applicazione di continuare a rispondere ad altre richieste mentre attende il completamento dell'operazione sul filesystem esterno.

  • Monitoraggio delle connessioni: implementa un sistema di monitoraggio che ti avvisi in caso di tempi di risposta elevati o errori di connessione con i filesystem esterni, permettendoti di risolvere il problema rapidamente.


Raccomandazioni generali:



  • Logging e monitoraggio: aggiungi un sistema di logging e monitoraggio che ti consenta di tracciare le performance delle query e identificare tempestivamente i problemi.

  • Test di carico: esegui test di carico per simulare situazioni reali di traffico e identificare potenziali colli di bottiglia nel sistema.


Logging e Monitoraggio Dettagliato


Un sistema di logging e monitoraggio ben implementato è essenziale per individuare e risolvere i problemi di performance in un'applicazione web. Questo sistema dovrebbe fornire una visione chiara di quanto tempo impiegano le singole query SQL e altri punti critici all'interno dello script, consentendo di identificare rapidamente eventuali colli di bottiglia.


1. Logging delle Query SQL


È fondamentale monitorare il tempo di esecuzione di ogni query SQL all'interno dello script PHP. Questo può essere fatto con un sistema di logging che registra:



  • Query eseguita: il testo della query SQL eseguita.

  • Tempo di esecuzione: il tempo impiegato per l'esecuzione della query, misurato in millisecondi.

  • Timestamp: il momento esatto in cui la query è stata eseguita.

  • Contesto: informazioni aggiuntive come l'utente che ha eseguito la query, la pagina o lo script che l'ha generata.


Implementazione:




  • PHP PDO: se stai usando PDO per le connessioni al database, puoi facilmente misurare il tempo di esecuzione delle query avvolgendole in un blocco di codice che utilizza microtime(true) prima e dopo l'esecuzione.


    $start_time = microtime(true);
    $stmt = $pdo->prepare($sql);
    $stmt->execute($params);
    $end_time = microtime(true);
    $execution_time = ($end_time - $start_time) * 1000; // Converti in millisecondi

    // Logga il tempo di esecuzione error_log("Query: $sql - Tempo di esecuzione: {$execution_time} ms");


 




  • Logging in un file o database: i dati raccolti possono essere memorizzati in un file di log dedicato o in una tabella del database per un'analisi successiva. Ad esempio, puoi scrivere un log come:


    error_log("[QUERY] {$sql} - [TEMPO] {$execution_time} ms - [TIMESTAMP] " . date('Y-m-d H:i:s'));


2. Logging dei punti critici dello script


Oltre a monitorare le query SQL, è importante tenere traccia dei tempi di esecuzione dei punti critici dello script PHP, come:



  • Connessioni a risorse esterne: connessioni a filesystem esterni, API di terze parti, o altri servizi esterni.

  • Esecuzione di funzioni particolarmente onerose: se lo script esegue operazioni intensive, come elaborazione di immagini, manipolazione di grandi quantità di dati, o calcoli complessi.

  • Inizio e fine dello script: per monitorare il tempo di esecuzione complessivo dello script.


Implementazione:




  • Misurazione dei tempi: Usa microtime(true) per registrare il tempo all'inizio e alla fine di ciascun punto critico.


    $start_time = microtime(true);

    // Esegui l'operazione critica

    critical_function();
    $end_time = microtime(true); $execution_time = ($end_time - $start_time) * 1000; // Tempo in millisecondi

    // Logga il tempo di esecuzione del punto critico error_log("Operazione critica - Tempo di esecuzione: {$execution_time} ms - [TIMESTAMP] " . date('Y-m-d H:i:s'));


 




  • Logging dettagliato: salva questi log in un file dedicato per le performance, separato dai log di errore standard, in modo da poterli analizzare facilmente.




3. Analisi e Monitoraggio Continuo


Una volta implementato il logging dettagliato, è importante analizzare regolarmente i dati raccolti per identificare:



  • Query lente o inefficienti: cerca query che richiedono molto tempo per essere eseguite e valuta se possono essere ottimizzate.

  • Punti critici con tempi di esecuzione elevati: identifica le parti dello script che impiegano più tempo e considera la possibilità di ottimizzare il codice o distribuire il carico su più server.

  • Pattern di performance nel tempo: analizza le performance a livello temporale per vedere se ci sono fluttuazioni legate a specifici eventi o carichi di traffico.


Strumenti avanzati:



  • Visualizzazione dei log: utilizza strumenti come Kibana o Grafana per visualizzare i log in modo grafico e identificare più facilmente i problemi di performance.

  • Monitoraggio in tempo reale: implementa soluzioni come New Relic, Datadog o strumenti simili per monitorare le performance in tempo reale e ricevere avvisi automatici in caso di degrado delle prestazioni.


4. Test di Carico e Stress Testing


Per completare il quadro, esegui regolarmente test di carico per simulare il traffico reale e stress test per capire come l'applicazione si comporta sotto carico estremo. Questo ti aiuterà a identificare eventuali colli di bottiglia che potrebbero non emergere durante il normale funzionamento.

Questo sito prevede l‘utilizzo di cookie. Continuando a navigare si considera accettato il loro utilizzo. Ulteriori informazioni. Accetto i cookie da questo sito