Skip to content

Bloat da Base de Dados

Visão Geral

A base de dados de produção contém uma quantidade anormal de dados acumulados que afetam diretamente a performance da aplicação. As tabelas principais responsáveis pelo problema são apresentadas abaixo.

pie title "Distribuicao do Espaco por Tabela (MB)" "icUrlTracker (457 MB)" : 457 "cmsPropertyData (255 MB)" : 255 "LogApp (188 MB)" : 188 "cmsPreviewXml (187 MB)" : 187 "Outras tabelas" : 100

Tabelas Problemáticas

1. icUrlTracker - 1.631.926 registos (457 MB)

Métrica Valor
Total de registos 1.631.926
Tamanho 457 MB
Valor normal < 10.000 registos
Fator de excesso ~163x

Esta é a tabela do pacote URL Tracker para Umbraco, responsável por rastrear alterações de URLs e gerir redirecionamentos 301. Com 1.6 milhões de registos, esta tabela é extremamente anormal.

Consequências:

  • A gestão de redirecionamentos no backoffice do Umbraco está completamente inoperacional (timeouts ao carregar a secção)
  • Cada cold start do Umbraco precisa de processar esta tabela
  • Queries que envolvem redirecionamentos são extremamente lentas

Solução: Limpar entradas antigas, mantendo apenas redirecionamentos ativos e recentes.


2. cmsPropertyData - 870.978 registos (255 MB)

Métrica Valor
Total de registos 870.978
Registos de versões antigas 838.525 (96,3%)
Registos necessários (últimas 2 versões) 32.453 (3,7%)
Tamanho 255 MB

Esta tabela armazena os valores de propriedades para cada versão de cada conteúdo. Como o Umbraco guarda todas as versões históricas, esta tabela cresce indefinidamente.

pie title "cmsPropertyData: Registos Necessarios vs. Desnecessarios" "Versoes antigas (eliminaveis): 838.525" : 838525 "Ultimas 2 versoes (manter): 32.453" : 32453

Solução: Eliminar dados de propriedades associados a versões antigas de conteúdo.


3. cmsContentVersion - 47.485 registos

Métrica Valor
Total de versões 47.485
Versões elimináveis 41.365 (87,1%)
Versões a manter (últimas 2 por nó) 6.120 (12,9%)

Alguns nós de conteúdo acumularam um número absurdo de versões. Isto acontece quando artigos são repetidamente guardados e publicados.

Nós Número de Versões Observação
Top 1 1.200+ versões Provavelmente um artigo editado frequentemente
Top 10 500+ versões cada Conteúdos com edição muito frequente
Média ~10 versões por nó Normal para a maioria

4. LogApp - 396.455 registos (188 MB)

Tabela de logs aplicacionais que nunca foi limpa. Pode ser truncada com segurança.


5. cmsPreviewXml - 45.403 registos (187 MB)

Cache XML de pré-visualização para cada versão de conteúdo. Cresce proporcionalmente ao número de versões. Após a limpeza de versões, esta tabela será drasticamente reduzida.


Impacto na Performance

flowchart LR A["BD com 1.6M registos\nem icUrlTracker"] --> B["Cold start lento\n(minutos)"] C["870K linhas em\ncmsPropertyData"] --> D["Cache XML enorme\n(> 2 GB em memoria)"] B --> E["Site parece em baixo"] D --> F["OutOfMemoryException"] E --> G["CRASH"] F --> G style G fill:#ff4444,color:#fff

Scripts de Limpeza

AVISO IMPORTANTE

Estes scripts devem ser executados primeiro em ambiente local ou de qualidade. Fazer BACKUP COMPLETO da base de dados antes de executar em produção!

1. Limpar icUrlTracker (manter últimos 30 dias)

-- AVISO: Executar primeiro em ambiente local ou qualidade!
-- Fazer BACKUP da base de dados antes de executar em producao!

-- 1. Limpar icUrlTracker (manter ultimos 30 dias)
DELETE FROM icUrlTracker WHERE Inserted < DATEADD(day, -30, GETDATE());

2. Limpar versões antigas de conteúdo (manter últimas 2 por nó)

-- Step 2a: Delete property data for old versions
DELETE pd FROM cmsPropertyData pd
WHERE pd.versionId IN (
    SELECT cv.VersionId FROM cmsContentVersion cv
    WHERE cv.VersionId NOT IN (
        SELECT TOP 2 cv2.VersionId 
        FROM cmsContentVersion cv2 
        WHERE cv2.ContentId = cv.ContentId 
        ORDER BY cv2.VersionDate DESC
    )
);

-- Step 2b: Delete preview XML for old versions  
DELETE px FROM cmsPreviewXml px
WHERE px.versionId IN (
    SELECT cv.VersionId FROM cmsContentVersion cv
    WHERE cv.VersionId NOT IN (
        SELECT TOP 2 cv2.VersionId 
        FROM cmsContentVersion cv2 
        WHERE cv2.ContentId = cv.ContentId 
        ORDER BY cv2.VersionDate DESC
    )
);

-- Step 2c: Delete old content versions
DELETE FROM cmsContentVersion 
WHERE VersionId NOT IN (
    SELECT TOP 2 cv2.VersionId 
    FROM cmsContentVersion cv2 
    WHERE cv2.ContentId = cmsContentVersion.ContentId 
    ORDER BY cv2.VersionDate DESC
);

3. Limpar logs antigos

-- 3. Limpar logs antigos
DELETE FROM LogApp WHERE DateCreated < DATEADD(month, -3, GETDATE());
TRUNCATE TABLE umbracoLog;

4. Reconstruir índices após limpeza

-- 4. Reconstruir indices apos limpeza
ALTER INDEX ALL ON cmsPropertyData REBUILD;
ALTER INDEX ALL ON cmsContentVersion REBUILD;
ALTER INDEX ALL ON icUrlTracker REBUILD;

Resultado Esperado Após Limpeza

Tabela Antes Depois (estimativa) Redução
icUrlTracker 1.631.926 registos (457 MB) ~5.000 registos (~1 MB) ~99,7%
cmsPropertyData 870.978 registos (255 MB) ~32.453 registos (~10 MB) ~96%
cmsContentVersion 47.485 registos ~6.120 registos ~87%
cmsPreviewXml 45.403 registos (187 MB) ~6.120 registos (~25 MB) ~87%
LogApp 396.455 registos (188 MB) ~10.000 registos (~5 MB) ~97%
Total estimado ~1.087 MB ~41 MB ~96%