Dovendo, mio malgrado, lavorare a diversi progetti che coinvolgono l’adozione di Magento, mi sono spesso dovuto spaccare la testa su come poter guadagnare qualche millesimo di secondo in meno nell’elaborazione delle varie pagine. Su tutte le domande, analizzando la struttura del database, e dopo aver ottimizzato in tutti i modi possibili le prestazioni del db, mi sono trovato a chiedermi come mai gli sviluppatori di Varien non abbiano mai fatto uso delle stored procedures offerte da MySql 5+.

Intuitivamente le stored procedures offrono diversi e intrinsechi vantaggi :

  1. Riduzione del traffico di rete: dove il db sia fisicamente ospitato su una macchina diversa dall’application server, l’invio continuo di query complesse con relativo ritorno di recordset altrettanto prolissi può essere un problema specialmente in condizioni di carichi particolarmente pesanti. La chiamata di una stored procedure (anche con parametri) riduce notevolmente i byte inviati al db.
  2. Algoritmi intensi di selezione e manipolazione dei dati sono più efficienti se gestiti all’interno del db, non all’interno dei processi di runtime dell’applicazione: tecnicamente non ha nessun senso inviare un’istruzione di selezione al db, ricevere il recordset di risposta, filtrarlo e manipolarlo, eventualmente richiedere al db un’altro recordset di normalizzazione e poi scegliere solo pochi dati da presentare nell’interfaccia utente. E’ un giro avanti e indietro assolutamente inefficiente.
  3. L’utilizzo di cursors all’interno delle stored procedures è di grande aiuto nell’eliminazione di query di tipo self-join o di union (che in molti casi richiedono un full table scan – Magento ne è pieno)
  4. Gli statement SQL sono già analizzati e non vi è necessità di effettuare un parse sintattico di ogni singola istruzione ricevuta.

Insomma, parrebbe essere una soluzione logica implementare correttamente le stored-procedures all’interno del db di Magento. Purtroppo non è così. A differenza di MSSQL o di ORACLE, che mantengono le stored procedure compilate in una cache globale, MySQL invece popola una cache di stored procedures all’interno del contesto di ogni singola connessione: questo potrebbe anche andare bene con i connettori che implementano il connection-pooling, cosa che però nel mondo PHP costituisce argomento molto controverso e di dubbia utilità. In altre parole … analizzando lo stato delle connessioni al db di Magento, si verificherà che una singola connessione viene attivata per ogni singolo processo e regolarmente chiusa al termine. L’implementazione delle stored procedures quindi risulterebbe addirittura dannosa dato che MySQL dovrebbe creare una cache di stored procedures ad ogni connessione e distruggerla alla chiusura.

Curioso che MySQL sia il db preferenziale per tutti gli sviluppatori PHP.