Uma loja PrestaShop em produção há cinco anos raramente pesa menos de 6 GB em base de dados. Muitas passam os 12 GB. Não é o catálogo que explode: um catálogo de 10 000 produtos com variantes, imagens e SEO completo cabe abaixo do gigabyte. O que incha são as tabelas lastro: tabelas técnicas que o PrestaShop alimenta continuamente e que nenhum processo nativo limpa. Ao fim de cinco anos, representam muitas vezes 70 % a 90 % do peso total da base.
Este artigo cartografa as tabelas culpadas, dá as consultas SQL para medir o ganho potencial e explica como montar uma política de retenção duradoura sem partir a loja. Não é uma checklist de revista: é a versão que aplicamos de facto em produção.
Porque é que uma base PrestaShop incha sem barulho
O PrestaShop não tem garbage collector. Todas as tabelas que registam eventos (pesquisas internas, ligações, carrinhos abandonados, registos, metadados órfãos) crescem linearmente, por vezes exponencialmente, sem que nenhum mecanismo nativo desencadeie uma limpeza.
Em concreto, numa loja com 2000 visitantes por dia:
ps_statssearchrecebe 300 a 800 linhas por dia (cada pesquisa interna, mesmo vazia).ps_connectionseps_connections_pageregistam cada visita e cada página vista. Conte 5000 a 15 000 linhas por dia.ps_guestcria um registo por cada visitante não autenticado.ps_cartguarda todos os carrinhos, abandonados incluídos, para sempre. Nalgumas lojas encontram-se 90 % de carrinhos vazios de 2018.ps_logcaptura todos os erros e eventos de administração.
Multiplique por 365 dias e 5 anos: falamos de dezenas de milhões de linhas com volume de negócio nulo. O peso bruto não é o pior problema. O custo real está noutro lado.
O custo escondido das tabelas lastro
1. Desempenho das consultas
O InnoDB carrega os índices em memória (buffer pool). Quando tabelas técnicas de vários GB monopolizam o buffer, as consultas de catálogo, carrinho e encomenda ficam mais lentas. O LCP de uma página de produto pode ganhar 200 a 400 ms só por causa da pressão de memória no MySQL.
2. Cópias de segurança e restauros
Um dump mysqldump de 12 GB demora 30 a 60 minutos consoante o disco. O restauro pode demorar 2 a 4 horas. Se a cópia automática do alojamento ultrapassar a janela horária, começa a falhar em silêncio. Muitas lojas descobrem que já não têm cópia válida no dia de um incidente.
3. Migrações bloqueadas
Migrar uma loja de 12 GB em PHP 8.2 para um servidor novo, ou para o PrestaShop 9, exige transferir o dump por rsync, restaurar e testar. O peso multiplica cada operação. As migrações «simples» tornam-se projetos de vários dias.
4. Módulos de terceiros que engordam
Alguns módulos de estatísticas, de marketing e de conectores ERP criam as suas próprias tabelas e deixam-nas crescer indefinidamente. ps_netreviews_, ps_advancedstats_ e ps_mailchimp_ são suspeitos frequentes. Uma auditoria revela muitas vezes uma tabela de 2 GB deixada por um módulo desinstalado há dois anos.
Auditoria: quanto pesa mesmo a sua base
Antes de qualquer limpeza, mede-se. Esta consulta lista as tabelas da base por tamanho decrescente:
SELECT
table_name AS 'Table',
ROUND(((data_length + index_length) / 1024 / 1024), 2) AS 'Size (MB)',
table_rows AS 'Rows'
FROM information_schema.TABLES
WHERE table_schema = DATABASE()
ORDER BY (data_length + index_length) DESC
LIMIT 30;
Obtém em geral um ranking parecido com este:
ps_statssearch: 1,8 GBps_connections_page: 1,2 GBps_pagenotfound: 800 MBps_connections: 600 MBps_log: 400 MBps_cart: 350 MBps_guest: 300 MBps_cart_rulemaisps_cart_cart_rule: 250 MB
Repare que ps_product, ps_product_lang e ps_orders raramente aparecem no top 10. Os dados de negócio reais são minoritários numa base PrestaShop antiga.
Cartografia das tabelas lastro e política de retenção
ps_statssearch: as pesquisas internas
Esta tabela regista cada palavra escrita na barra de pesquisa. Guardar o histórico para além de 90 dias não tem qualquer interesse analítico: as tendências de pesquisa de 2019 não esclarecem nada em 2026. Política recomendada: retenção de 90 dias.
-- Auditoria
SELECT COUNT(*) AS total, MIN(date_add) AS mais_antigo
FROM ps_statssearch;
-- Eliminação para além de 90 dias
DELETE FROM ps_statssearch
WHERE date_add < DATE_SUB(NOW(), INTERVAL 90 DAY);
ps_connections e ps_connections_page: o histórico de visitas
Se usa o GA4 ou o Matomo, estas tabelas são redundantes. O PrestaShop enche-as para o seu próprio módulo de estatísticas que ninguém consulta. Política: retenção de 30 dias, ou 0 se tiver uma ferramenta externa.
ps_pagenotfound: os 404
Útil para identificar ligações partidas e programar redirecionamentos 301. Mas, depois de tratado, o histórico deixa de servir. Política: retenção de 60 dias, depois de extrair os 404 recorrentes.
ps_cart: os carrinhos abandonados
Subtil. Os carrinhos recentes servem para o retargeting e as recuperações. Para além de 90 dias, um carrinho abandonado está estatisticamente perdido. Política: conservar 90 dias, mas não tocar nos carrinhos ligados a encomendas (tabela ligada ps_orders.id_cart).
-- Eliminação segura: apenas os carrinhos SEM encomenda associada
DELETE c FROM ps_cart c
LEFT JOIN ps_orders o ON o.id_cart = c.id_cart
WHERE o.id_cart IS NULL
AND c.date_add < DATE_SUB(NOW(), INTERVAL 90 DAY);
ps_guest: os visitantes não autenticados
Ligada a ps_customer e ps_connections. Limpeza com precaução: um guest convertido em customer tem de ser preservado. Política: eliminar os guests sem customer e sem ligação recente.
ps_log: os registos de administração
Útil para depuração recente, sem valor passado um mês. Política: retenção de 30 dias.
Metadados órfãos
Quando elimina um produto, algumas tabelas ligadas guardam linhas órfãs: ps_image, ps_feature_product, ps_specific_price, ps_product_attachment. O mesmo para as categorias, fabricantes e fornecedores eliminados. Essas linhas não servem para nada e falseiam as junções.
-- Exemplo: ps_image órfãs
SELECT i.id_image FROM ps_image i
LEFT JOIN ps_product p ON p.id_product = i.id_product
WHERE p.id_product IS NULL;
A armadilha do DELETE em produção
Eliminar um milhão de linhas numa única consulta numa tabela InnoDB bloqueada pela administração e pela montra é a garantia de uma queda. O binary log explode, a replicação descola, o servidor pode entrar em swap.
A regra absoluta: eliminar por lotes de 5000 a 10 000 linhas no máximo, com uma pausa de 100 ms entre cada lote.
-- Ciclo de eliminação por lotes (pseudocódigo)
DO WHILE rows_affected > 0:
DELETE FROM ps_statssearch
WHERE date_add < DATE_SUB(NOW(), INTERVAL 90 DAY)
LIMIT 5000;
SLEEP 0.1;
END DO;
E sistematicamente: dry-run antes de executar. Quer saber quantas linhas vão desaparecer e quanto espaço recupera antes de clicar.
Automatizar a retenção: a estratégia correta
Fazer a limpeza à mão uma vez e esquecê-la não serve de nada: a base volta a inchar. A retenção tem de ser contínua e automática:
- Cron diário que executa a política de retenção de cada tabela.
- Token de segurança para que o cron não possa ser disparado a partir do exterior.
- Registos de execução para seguir o que foi eliminado.
- Notificação em caso de falha ou de anomalia (volume anormal de eliminação).
- OPTIMIZE TABLE semanal nas tabelas limpas para recuperar o espaço em disco (senão o InnoDB conserva o espaço alocado).
O nosso módulo dfcleanup: o método empacotado
Implementar esta estratégia à mão exige dois a três dias de desenvolvimento e outro tanto de testes. O nosso módulo dfcleanup para PrestaShop 8 e 9 industrializa todo o método descrito aqui:
- Seis limpadores especializados: pesquisas, carrinhos, registos, estatísticas, metadados órfãos, imagens órfãs. Cada um com a sua retenção configurável.
- Três modos: Auditoria (só leitura), Dry-run (simulação registada), Execute (eliminação por lotes de 5000 linhas).
- Ganho em MB calculado antes da ação, por limpador e no total.
- Tarefa cron protegida por token, pronta a usar.
- Registos detalhados e compatibilidade com PrestaShop 8 e 9.
Por 19 €, evita as consultas DELETE à mão e instala uma política de retenção duradoura. Comparado com o tempo de desenvolvimento e com o custo de um incidente de base de dados, é um dos módulos com melhor retorno do catálogo.
FAQ
É preciso fazer OPTIMIZE TABLE depois de cada DELETE?
Não, não depois de cada DELETE: é caro em I/O e bloqueia a tabela. Uma vez por semana ou por mês, em hora de menor tráfego, nas tabelas que sofreram uma limpeza massiva. O OPTIMIZE TABLE recupera o espaço em disco que o InnoDB não liberta naturalmente depois da eliminação.
A limpeza pode afetar o SEO ou as estatísticas?
Sem impacto no SEO: as tabelas limpas são técnicas (pesquisas internas, ligações, registos), não o catálogo nem os URL. Do lado das estatísticas, se usa o GA4 ou o Matomo, os dados estão guardados lá; a base PrestaShop é redundante. Se usa as estatísticas nativas do PS, configure uma retenção mais longa (180 dias, por exemplo).
Que retenção para os carrinhos abandonados?
90 dias chegam largamente. As ferramentas de recuperação de carrinho (e-mail, retargeting) disparam nas 24 a 72 horas. Para além de 90 dias, a probabilidade de recuperação é estatisticamente nula. E nunca elimina um carrinho convertido em encomenda: a junção ps_orders.id_cart protege esse dado, que aliás tem de ser conservado 10 anos pelas regras contabilísticas portuguesas.
Que ganho esperar em concreto?
Numa loja de 5 anos com 2000 visitantes por dia, medimos em média 60 % a 80 % de redução da base na primeira passagem. Uma loja de 12 GB desce para 3 ou 4 GB. As passagens seguintes estabilizam a base num patamar próximo do «peso real do negócio».
O módulo é compatível com multiloja?
Sim. Os limpadores respeitam o perímetro multiloja quando é relevante (carrinhos, pesquisas por loja). As tabelas globais (registos, ligações) são limpas globalmente.
Para ir mais longe
A dívida de base de dados é uma das três fontes principais de degradação do desempenho a longo prazo de uma loja PrestaShop, com os módulos de terceiros obsoletos e as imagens mal otimizadas. Veja também a nossa checklist Core Web Vitals 2026 para o resto do quadro, e o guia PrestaShop 9 vs 8 se prepara uma migração: aligeirar a base antes de migrar pode dividir por 5 o tempo de mudança.