Ottimizzazione delle prestazioni del tuo negozio PrestaShop: dalle query al Full Page Cache

Ogni query conta: perché le performance del database sono il collo di bottiglia nascosto del tuo negozio

Ho analizzato oltre 200 negozi PrestaShop negli ultimi cinque anni. Ogni singola volta — senza eccezioni — il miglioramento delle performance più grande arriva dal livello database. Non da un CDN. Non dalla compressione delle immagini. Non dall'ennesimo plugin di cache. Il database.

Monitoraggio delle prestazioni del server per l'ottimizzazione delle query del database PrestaShop

Un tipico caricamento pagina PrestaShop esegue tra 80 e 300 query SQL. Su un negozio con 10.000+ prodotti, quel numero può superare le 500 nelle pagine categoria con navigazione a faccette. Quando anche solo una manciata di quelle query impiega 200ms invece di 2ms, il tuo Time to First Byte (TTFB) si gonfia, la CPU del server va in picco e il tasso di conversione crolla. La ricerca di Google stessa mostra che un aumento di 100ms nel tempo di caricamento riduce le conversioni fino al 7%.

Questo articolo non è una panoramica generica su "come rendere PrestaShop più veloce". Vado in profondità sulle performance del database — identificare le query lente, comprendere i piani di esecuzione, ottimizzare InnoDB, scegliere gli indici giusti e ripulire il bloat dei dati che silenziosamente uccide il tuo negozio. Se hai già letto la nostra guida generale alle performance, considera questo il capitolo successivo.

Step 1: Abilita lo Slow Query Log — il tuo miglior strumento diagnostico

Prima di ottimizzare qualsiasi cosa, devi vedere cosa è realmente lento. Lo slow query log di MySQL registra ogni query che supera una soglia di tempo che definisci tu. Ho perso il conto di quanti proprietari di negozi saltano questo passaggio e vanno direttamente ad "aggiungere Redis" — è come prendere antidolorifici senza diagnosticare il problema.

Abilitare lo Slow Query Log

Aggiungi queste righe al tuo file di configurazione MySQL o MariaDB (tipicamente /etc/mysql/mysql.conf.d/mysqld.cnf o /etc/mysql/mariadb.conf.d/50-server.cnf):

# Enable slow query logging
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow-query.log
long_query_time = 0.5
log_queries_not_using_indexes = 1
min_examined_row_count = 100

Le impostazioni chiave:

  • long_query_time = 0.5 — Registra qualsiasi query che impiega più di 500ms. Il valore predefinito di 10 secondi è assurdamente alto per l'e-commerce; quando una query impiega 10 secondi, il tuo cliente se n'è andato 8 secondi prima.
  • log_queries_not_using_indexes = 1 — Intercetta le query che fanno full table scan anche se sono veloci su dataset piccoli. Sono bombe a orologeria che esplodono quando il tuo catalogo cresce.
  • min_examined_row_count = 100 — Filtra le query banali così il tuo log rimane focalizzato sui problemi reali.

Dopo l'abilitazione, riavvia MySQL e lascia raccogliere dati per almeno 24 ore coprendo un intero ciclo di traffico. Poi analizza:

# Summarize the worst offenders
mysqldumpslow -s t -t 20 /var/log/mysql/slow-query.log

# Or use pt-query-digest from Percona Toolkit for deeper analysis
pt-query-digest /var/log/mysql/slow-query.log > /tmp/query-report.txt

pt-query-digest dal Percona Toolkit è il gold standard qui. Raggruppa le query simili, le classifica per tempo totale di esecuzione e ti mostra esattamente dove il tuo database passa il suo tempo. Installalo — è gratuito e disponibile nella maggior parte dei package manager.

Step 2: Leggere i piani EXPLAIN — la competenza che separa l'intuizione dalla conoscenza

Una volta identificate le query lente, il passo successivo è capire perché sono lente. Il comando EXPLAIN di MySQL ti mostra il piano di esecuzione della query — come l'ottimizzatore decide di recuperare i tuoi dati.

EXPLAIN SELECT p.id_product, pl.name, p.price
FROM ps_product p
LEFT JOIN ps_product_lang pl ON p.id_product = pl.id_product AND pl.id_lang = 1
LEFT JOIN ps_category_product cp ON p.id_product = cp.id_product
WHERE cp.id_category = 42 AND p.active = 1
ORDER BY p.date_add DESC;

Cosa cercare nell'output

ColonnaSegnale d'allarmeCosa significa
typeALLFull table scan — MySQL legge ogni riga. Accettabile solo su tabelle minuscole.
typeindexFull index scan — meglio di ALL, ma legge comunque ogni voce dell'indice.
possible_keysNULLNessun indice disponibile. L'ottimizzatore non ha nulla con cui lavorare.
keyNULLNessun indice scelto anche se esistono opzioni. Di solito significa che le statistiche dell'indice sono obsolete.
rowsNumero altoRighe stimate esaminate. Confronta con il conteggio dei risultati reali — un rapporto 50.000:12 segnala un indice mancante.
ExtraUsing temporaryMySQL crea una tabella temporanea, spesso riversandola su disco.
ExtraUsing filesortRisultati ordinati in memoria o su disco anziché tramite l'ordine dell'indice.

L'output EXPLAIN ideale mostra type: ref o type: eq_ref, una key specifica in uso e una stima rows bassa. Quando vedi type: ALL combinato con Using temporary; Using filesort, hai trovato una query che fa il massimo lavoro per il minimo risultato.

Un esempio reale con PrestaShop

Una delle query lente più comuni che incontro nei negozi PrestaShop coinvolge la tabella ps_specific_price. Nei negozi con migliaia di prezzi specifici (sconti quantità, prezzi per gruppo, promozioni con date), questo pattern di query appare costantemente nello slow log:

EXPLAIN SELECT * FROM ps_specific_price
WHERE id_product = 1542
AND id_shop IN (0, 1)
AND id_currency IN (0, 1)
AND id_country IN (0, 8)
AND id_group IN (0, 1, 3)
AND id_customer = 0
AND from_quantity >= 1
AND (from = '0000-00-00 00:00:00' OR from <= NOW())
AND (to = '0000-00-00 00:00:00' OR to >= NOW());

Su un negozio con 200.000+ righe in specific_price, questa query esaminava 180.000 righe per restituirne 3. La soluzione era un indice composito:

ALTER TABLE ps_specific_price
ADD INDEX idx_product_shop_currency
(id_product, id_shop, id_currency, id_country);

Risultato: il tempo della query è sceso da 340ms a 0,8ms. Su una pagina categoria che carica 36 prodotti, quel singolo indice ha risparmiato 12 secondi di tempo query cumulativo per caricamento pagina.

Step 3: Le tabelle più problematiche di PrestaShop — e come sistemarle

Dopo aver analizzato gli slow query log di decine di negozi, queste tabelle sono responsabili della maggior parte dei problemi di performance del database:

ps_connections e ps_connections_page

Queste tabelle registrano ogni connessione di ogni visitatore e ogni pagina visualizzata. Su un negozio che riceve 5.000 visitatori giornalieri con una media di 4 pagine ciascuno, sono 20.000 righe al giorno — 7,3 milioni di righe all'anno. Ho visto negozi con 50 milioni di righe in ps_connections_page che non erano mai state pulite.

-- Check the damage
SELECT table_name, table_rows,
  ROUND(data_length/1024/1024, 2) AS data_mb,
  ROUND(index_length/1024/1024, 2) AS index_mb
FROM information_schema.tables
WHERE table_schema = 'prestashop'
AND table_name IN ('ps_connections', 'ps_connections_page',
  'ps_log', 'ps_mail', 'ps_guest', 'ps_pagenotfound');

-- Clean old connection data (keep 90 days)
DELETE FROM ps_connections_page
WHERE id_connections IN (
  SELECT id_connections FROM ps_connections
  WHERE date_add < DATE_SUB(NOW(), INTERVAL 90 DAY)
);
DELETE FROM ps_connections WHERE date_add < DATE_SUB(NOW(), INTERVAL 90 DAY);

-- Clean old logs (keep 30 days)
DELETE FROM ps_log WHERE date_add < DATE_SUB(NOW(), INTERVAL 30 DAY);

-- Clean sent emails log (keep 60 days)
DELETE FROM ps_mail WHERE date_add < DATE_SUB(NOW(), INTERVAL 60 DAY);

-- Clean 404 tracking (keep 30 days)
DELETE FROM ps_pagenotfound WHERE date_add < DATE_SUB(NOW(), INTERVAL 30 DAY);

Importante: Dopo eliminazioni massicce, recupera lo spazio su disco:

OPTIMIZE TABLE ps_connections, ps_connections_page, ps_log, ps_mail, ps_guest;

ps_cart e ps_cart_product

I carrelli abbandonati si accumulano all'infinito. Un negozio di 5 anni potrebbe avere 2 milioni di record cart con 8 milioni di righe cart_product, il 95% delle quali non convertirà mai. Pulisci i carrelli più vecchi di 6 mesi che non hanno un ordine associato:

-- Identify orphan carts (no order placed)
DELETE cp FROM ps_cart_product cp
INNER JOIN ps_cart c ON cp.id_cart = c.id_cart
LEFT JOIN ps_orders o ON c.id_cart = o.id_cart
WHERE o.id_cart IS NULL
AND c.date_add < DATE_SUB(NOW(), INTERVAL 180 DAY);

DELETE c FROM ps_cart c
LEFT JOIN ps_orders o ON c.id_cart = o.id_cart
WHERE o.id_cart IS NULL
AND c.date_add < DATE_SUB(NOW(), INTERVAL 180 DAY);

ps_search_index e ps_search_word

L'indice di ricerca prodotti può crescere enormemente su cataloghi grandi. Dopo la pulizia dei prodotti o aggiornamenti di massa, ricostruiscilo:

-- Nuclear option: truncate and rebuild
TRUNCATE TABLE ps_search_index;
TRUNCATE TABLE ps_search_word;

-- Then trigger a full reindex via CLI:
php bin/console prestashop:search:reindex

Step 4: Strategia degli indici per le tabelle dei moduli PrestaShop

Se sviluppi moduli — o usi moduli di terze parti che creano tabelle personalizzate — l'indicizzazione è una tua responsabilità. Le tabelle core di PrestaShop vengono fornite con indici ragionevoli, ma le tabelle dei moduli spesso non ne hanno.

Principi per un'indicizzazione efficace

  1. Indicizza le colonne usate nelle clausole WHERE — Se il tuo modulo interroga WHERE id_product = X AND id_shop = Y, crea un indice composito su (id_product, id_shop).
  2. L'ordine delle colonne conta negli indici compositi — Metti per prima la colonna più selettiva. Una colonna con 10.000 valori unici dovrebbe precedere una con 3 valori unici.
  3. Copri il tuo ORDER BY — Se ordini frequentemente per date_add DESC, includi date_add nell'indice per evitare operazioni di filesort.
  4. Non esagerare con gli indici — Ogni indice rallenta le operazioni INSERT e UPDATE. Per una tabella con molte scritture (come una tabella di log), pensaci bene prima di aggiungere indici.
-- Example: module review table with common query patterns
CREATE TABLE ps_mymodule_reviews (
  id_review INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  id_product INT UNSIGNED NOT NULL,
  id_customer INT UNSIGNED NOT NULL,
  id_shop INT UNSIGNED NOT NULL DEFAULT 1,
  rating TINYINT UNSIGNED NOT NULL,
  status TINYINT NOT NULL DEFAULT 0,
  date_add DATETIME NOT NULL,

  -- Composite index for "show approved reviews for product X"
  INDEX idx_product_status (id_product, status, date_add),

  -- Index for "show all reviews by customer"
  INDEX idx_customer (id_customer),

  -- Index for admin list with shop filter
  INDEX idx_shop_status (id_shop, status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

Trovare indici mancanti sulle tabelle esistenti

-- List all module tables without non-primary indexes
SELECT t.table_name, t.table_rows
FROM information_schema.tables t
LEFT JOIN information_schema.statistics s
  ON t.table_name = s.table_name
  AND t.table_schema = s.table_schema
  AND s.index_name != 'PRIMARY'
WHERE t.table_schema = 'prestashop'
AND t.table_name LIKE 'ps_%'
AND t.table_rows > 1000
AND s.index_name IS NULL
ORDER BY t.table_rows DESC;

Questa query rivela le tabelle con oltre 1.000 righe e nessun indice secondario — candidati perfetti per l'ottimizzazione.

Step 5: Configurazione InnoDB — le impostazioni che contano davvero

InnoDB è il motore di storage di PrestaShop. La sua configurazione predefinita è progettata per un carico di lavoro generico su hardware modesto. Per un server database dedicato all'e-commerce, devi ottimizzarlo.

Ottimizzazione del database e configurazione della cache full page per un PrestaShop più veloce

Le impostazioni critiche

[mysqld]
# === Buffer Pool: The Single Most Important Setting ===
# Set to 70-80% of available RAM on a dedicated DB server.
# For shared hosting: 50% of RAM, minimum 1GB.
innodb_buffer_pool_size = 4G

# Split the buffer pool into instances (1 per GB)
innodb_buffer_pool_instances = 4

# === Log Files: Larger = Fewer Disk Writes ===
# Default 48M is too small. Set to 25% of buffer pool, max 2G each.
innodb_log_file_size = 1G
innodb_log_buffer_size = 64M

# === Flush Behavior ===
# 1 = Full ACID (safest, slower)
# 2 = Flush to OS buffer each commit, disk write once/sec (good compromise)
# 0 = Flush once/sec (fastest, risks 1 sec of data on crash)
innodb_flush_log_at_trx_commit = 2

# Use O_DIRECT to avoid double-buffering with OS page cache
innodb_flush_method = O_DIRECT

# === I/O Capacity ===
# SSD: 2000-4000. HDD: 200-400. Cloud SSD: 1000-2000.
innodb_io_capacity = 2000
innodb_io_capacity_max = 4000

# === Thread Concurrency ===
innodb_read_io_threads = 4
innodb_write_io_threads = 4
innodb_purge_threads = 4

# === Per-Table Tablespace (default in MySQL 5.7+, verify it's on) ===
innodb_file_per_table = 1

# === Temp Tables ===
tmp_table_size = 64M
max_heap_table_size = 64M

# === Sort and Join Buffers (per-connection, don't over-allocate) ===
sort_buffer_size = 2M
join_buffer_size = 4M
read_buffer_size = 2M
read_rnd_buffer_size = 1M

# === Connection Pool ===
max_connections = 200
thread_cache_size = 100

# === Table Cache ===
table_open_cache = 4000
table_definition_cache = 2000

# === Disable Performance Schema in Production (saves ~400MB RAM) ===
performance_schema = OFF

Comprendere innodb_buffer_pool_size

Questa è la singola impostazione MySQL più impattante per PrestaShop. Il buffer pool è dove InnoDB memorizza nella cache i dati delle tabelle e gli indici in memoria. Quando una query necessita di dati già nel buffer pool, vengono serviti dalla RAM anziché dal disco — ordini di grandezza più veloce.

Come dimensionarlo:

-- Check your total database size
SELECT ROUND(SUM(data_length + index_length) / 1024 / 1024 / 1024, 2) AS total_gb
FROM information_schema.tables
WHERE table_schema = 'prestashop';

-- Check buffer pool hit ratio (should be > 99%)
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_read_requests';
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_reads';

-- Calculate: hit_ratio = 1 - (reads / read_requests) * 100
-- If below 99%, increase buffer_pool_size

Un benchmark reale da test di Releem su MariaDB 10.5 con un negozio PrestaShop ha mostrato che un'ottimizzazione corretta di InnoDB (buffer pool dimensionato a 3,2GB per un database da 1GB) ha ridotto il tempo di risposta del 39% — da 610ms a 370ms — e aumentato le query al secondo del 53%.

Query Cache: MariaDB vs MySQL 8

Questo è un argomento frequentemente frainteso. MySQL 8.0 ha rimosso completamente la query cache. Oracle ha determinato che la contesa del mutex della cache causava più problemi di quanti ne risolvesse su scala. MariaDB, invece, la supporta ancora e può aiutare i negozi PrestaShop con carichi di lavoro prevalentemente in lettura.

Per MariaDB (10.5+):

query_cache_type = 1
query_cache_size = 64M
query_cache_limit = 2M

Per MySQL 8.0+: Non provare ad attivarla — non esiste. Invece, affidati a un buffer pool dimensionato correttamente e considera il caching a livello applicativo con Redis.

Se sei su MySQL 8 e stai considerando un passaggio, MariaDB 10.11 è completamente compatibile con PrestaShop e molti provider di hosting la offrono come sostituzione diretta.

Step 6: Pattern di query specifici di PrestaShop a cui prestare attenzione

Oltre all'ottimizzazione generale di MySQL, PrestaShop ha pattern di query specifici che causano problemi di performance su larga scala. Ecco quelli che incontro più frequentemente:

Il problema del conteggio prodotti

La navigazione a faccette di PrestaShop esegue query COUNT per ogni combinazione di filtri. Su una categoria con 15 gruppi di attributi e 200 attributi, questo può generare oltre 200 query COUNT individuali per caricamento pagina. Ogni query sembra innocua:

SELECT COUNT(DISTINCT p.id_product)
FROM ps_product p
INNER JOIN ps_product_attribute_combination pac ...
WHERE ... AND pac.id_attribute = 47;

Ma 200 di esse a 10ms ciascuna equivalgono a 2 secondi di puro tempo query. La soluzione è usare una tabella indice pre-calcolata (che moduli come i nostri moduli SEO e performance possono fornire) o ridurre i filtri visibili tramite la configurazione della categoria.

Il problema N+1 query negli hook dei moduli

Un modulo registrato su displayProductListReviews che esegue una query per prodotto crea un problema N+1. Se la tua pagina categoria mostra 36 prodotti, sono 36 query aggiuntive — per modulo:

// Bad: query per product in a list hook
public function hookDisplayProductListReviews($params) {
    $id_product = (int)$params['product']['id_product'];
    $result = Db::getInstance()->getRow(
        'SELECT AVG(rating) as avg_rating
         FROM ps_mymodule_reviews
         WHERE id_product = ' . $id_product
    );
    // ...
}

// Good: batch query all products at once, cache the result
public function hookActionProductSearchAfter($params) {
    $products = $params['result']->getProducts();
    $ids = array_column($products, 'id_product');

    $ratings = Db::getInstance()->executeS(
        'SELECT id_product, AVG(rating) as avg_rating
         FROM ps_mymodule_reviews
         WHERE id_product IN (' . implode(',', array_map('intval', $ids)) . ')
         GROUP BY id_product'
    );
    // Store in static cache for use in display hook
}

Valutazione delle regole carrello

I negozi con centinaia di regole carrello attive soffrono ad ogni caricamento della pagina carrello. Le condizioni di ogni regola carrello (restrizioni prodotto, restrizioni categoria, gruppi clienti) attivano query separate. Se hai più di 50 regole carrello attive, considera di:

  • Archiviare le regole scadute (imposta il loro active a 0 e date_to a una data passata)
  • Consolidare le regole sovrapposte dove possibile
  • Aggiungere un indice su ps_cart_rule.active, ps_cart_rule.date_from, ps_cart_rule.date_to

Step 7: Monitoraggio in produzione — non configurare e dimenticare

L'ottimizzazione del database non è un'attività una tantum. I dati del tuo negozio crescono, i pattern di traffico cambiano e gli aggiornamenti dei moduli possono introdurre nuovi pattern di query. Configura un monitoraggio continuo:

Metriche essenziali da monitorare

-- Buffer pool efficiency (check weekly)
SELECT
  FORMAT(VARIABLE_VALUE, 0) AS buffer_pool_read_requests
FROM performance_schema.global_status
WHERE VARIABLE_NAME = 'Innodb_buffer_pool_read_requests';

-- Slow queries per hour (should trend downward)
SHOW GLOBAL STATUS LIKE 'Slow_queries';

-- Table lock waits (should be near zero for InnoDB)
SHOW GLOBAL STATUS LIKE 'Table_locks_waited';

-- Temporary tables created on disk (high = increase tmp_table_size)
SHOW GLOBAL STATUS LIKE 'Created_tmp_disk_tables';
SHOW GLOBAL STATUS LIKE 'Created_tmp_tables';

-- Thread connection usage
SHOW GLOBAL STATUS LIKE 'Threads_connected';
SHOW GLOBAL STATUS LIKE 'Max_used_connections';

Monitoraggio automatizzato

Per i negozi dove il downtime significa perdita reale di ricavi, considera queste soluzioni di monitoraggio:

  • Percona Monitoring and Management (PMM) — Gratuito, open source, dashboard complete per MySQL/MariaDB con analytics delle query. È quello che uso per tutti i negozi dei clienti.
  • Releem — Tuning automatizzato di MySQL che regola i parametri in base al tuo carico di lavoro reale. Utile se non vuoi ottimizzare manualmente my.cnf.
  • MySQLTuner — Uno script Perl che fornisce raccomandazioni rapide: perl mysqltuner.pl --host 127.0.0.1

Step 8: Quando aggiungere Redis — e cosa risolve realmente

Redis non è un sostituto dell'ottimizzazione del database. È un livello superiore. Se le tue query sottostanti sono lente, Redis maschera il problema per le richieste in cache e lo peggiora quando la cache scade (thundering herd).

Dopo aver ottimizzato i tuoi indici, pulito le tabelle e configurato InnoDB — allora aggiungi Redis per:

  • Storage delle sessioni — Elimina il file locking sotto richieste concorrenti. Configura in config/defines.inc.php o usa il session handler di Symfony.
  • Cache Smarty — Impedisce a Smarty di scrivere migliaia di file di template compilati su disco.
  • Cache Symfony — Metadati Doctrine, routing e cache del container dei servizi serviti dalla memoria.
  • Caching a livello modulo — Qualsiasi dato del modulo costoso da calcolare ma che cambia raramente.

Il risultato: su un negozio correttamente ottimizzato, aggiungere Redis riduce tipicamente il TTFB di un ulteriore 30-50%. La nostra guida alle performance copre la configurazione di Redis in dettaglio.

Step 9: Full Page Cache — il livello finale

Una volta che il tuo database è snello e la cache applicativa è in Redis, l'ottimizzazione definitiva è eliminare completamente l'esecuzione PHP per i visitatori anonimi. Varnish o nginx FastCGI cache possono servire una pagina completamente renderizzata in meno di 10ms — rispetto ai 200-500ms per una pagina renderizzata da PHP.

La sfida con PrestaShop è l'invalidazione della cache. Cambi di prezzo, aggiornamenti stock, inizio/fine promozioni e modifiche al carrello richiedono tutti:

  • Invalidazione basata su tag — Il modulo xkey di Varnish ti permette di taggare le pagine in cache per prodotto, categoria o pagina CMS e purgarle selettivamente.
  • Approccio basato su TTL — Metti in cache le pagine per 5-15 minuti e accetta una breve obsolescenza. Adatto alla maggior parte dei negozi dove la precisione dello stock al secondo non è critica.
  • Approccio ibrido — Metti in cache lo scheletro della pagina, usa ESI (Edge Side Includes) o JavaScript per i frammenti dinamici come il widget carrello e lo stato di login.

Per i negozi ad alto traffico, la combinazione di database ottimizzato + cache applicativa Redis + FPC Varnish raggiunge routinariamente un TTFB sotto i 50ms. Uno dei nostri clienti con un catalogo di 15.000 prodotti è passato da 800ms di TTFB a 120ms usando esattamente questo stack.

L'ordine di priorità: massimo impatto, minimo rischio

Se porti a casa una sola cosa da questo articolo, è questa lista di priorità:

  1. Abilita lo slow query log e sistema le 10 query peggiori — Impatto immediato, costo zero, nessun rischio.
  2. Pulisci le tabelle gonfieps_connections, ps_log, ps_mail, carrelli abbandonati. Recupero immediato di spazio e performance.
  3. Ottimizza il buffer pool InnoDB — Un singolo cambio di impostazione in my.cnf, impatto massiccio.
  4. Aggiungi gli indici mancanti sulle tabelle dei moduli — Alto impatto se usi moduli con molti dati.
  5. Aggiungi Redis per sessioni e cache — Piano di performance affidabile, elimina il collo di bottiglia I/O su file.
  6. Implementa la full page cache — Il moltiplicatore finale per i negozi ad alto traffico.

Ogni step si basa sul precedente. Saltare allo step 6 senza aver fatto gli step 1-4 è costruire su fondamenta instabili.

Se non sei sicuro di dove si trova il tuo negozio, inizia con lo slow query log. Ventiquattro ore di dati ti diranno più di qualsiasi plugin di performance. E se hai bisogno di aiuto per interpretare quello che trovi, contattaci — l'analisi delle performance del database è una delle cose che facciamo meglio.

David Miller sviluppa strumenti di performance per PrestaShop e ottimizza database e-commerce dal 2017. I suoi moduli sono disponibili su mypresta.rocks.

Condividi questo articolo:
David Miller

David Miller

Oltre un decennio di esperienza pratica con PrestaShop. David sviluppa moduli e-commerce ad alte prestazioni focalizzati su SEO, ottimizzazione del checkout e gestione del negozio. Appassionato di...

Ti è piaciuto questo articolo?

Ricevi i nostri ultimi consigli, guide e aggiornamenti dei moduli nella tua casella di posta.

Commenti (3)

P
Piotr Nowak 14/02/2026
Good article but I think you should mention the opcache preloading feature for PHP 8.1+. It made a big difference for us combined with the query optimizations you described.
Rispondi
L
Laura Bianchi 14/02/2026
Implemented the Redis full page cache approach you described here. Our TTFB went from 800ms to 120ms. Incredible difference for our catalog of 15k products.
Rispondi
D
David Miller 14/02/2026
Amazing results Laura! Redis FPC is a game changer especially for large catalogs. If you want to squeeze even more out of it, try combining it with Varnish as a reverse proxy.

Lascia un commento

Loading...
Back to top