Database Indexes

Análise e Otimização de Índices - C-Suite

Visão Geral

Este documento descreve o processo de análise e otimização de índices de banco de dados para o ecossistema C-Suite. Índices adequados são essenciais para performance, especialmente em tabelas grandes e queries frequentes.

Script de Análise

Localização

O script principal está em: scripts/analyze_database_indexes.py

Uso Básico

# Analisar banco csuite usando configuração centralizada
python scripts/analyze_database_indexes.py --database csuite --config

# Analisar banco core
python scripts/analyze_database_indexes.py --database core --config

# Analisar com credenciais manuais
python scripts/analyze_database_indexes.py \
    --database csuite \
    --host localhost \
    --user root \
    --password senha

# Gerar SQL para criar índices sugeridos
python scripts/analyze_database_indexes.py \
    --database csuite \
    --config \
    --output indexes_suggestions.sql

Padrões de Índices

Índices de Alta Prioridade

Estes índices são essenciais e devem ser criados primeiro:

  1. Foreign Keys: Todas as colunas que são chaves estrangeiras
  2. organization_id, org_id
  3. customer_id
  4. user_id
  5. Qualquer coluna terminando em _id

  6. Timestamps para Filtros: Colunas de data usadas em WHERE

  7. created_at
  8. updated_at
  9. deleted_at
  10. Qualquer coluna com _date ou date

  11. Índices Compostos Comuns:

  12. (organization_id, created_at) - Filtro por org + data
  13. (customer_id, status) - Filtro por cliente + status
  14. (organization_id, enabled, created_at) - Filtro complexo comum

Índices de Média Prioridade

Estes índices melhoram performance mas não são críticos:

  1. Status Flags: Colunas booleanas usadas em filtros
  2. enabled
  3. active
  4. deleted
  5. status

  6. Lookup Fields: Campos usados para busca

  7. email
  8. phone
  9. name
  10. key, code

Tabelas Principais

Banco csuite

organizations

-- Já deve ter PRIMARY KEY em id
CREATE INDEX idx_organizations_created_at ON csuite.organizations(created_at);

policy_rules

-- Já tem UNIQUE KEY em (organization_id, rule_key)
CREATE INDEX idx_policy_rules_enabled ON csuite.policy_rules(enabled);
CREATE INDEX idx_policy_rules_org_enabled ON csuite.policy_rules(organization_id, enabled);

metric_definitions

CREATE INDEX idx_metric_definitions_org ON csuite.metric_definitions(organization_id);
CREATE INDEX idx_metric_definitions_key ON csuite.metric_definitions(metric_key);
CREATE INDEX idx_metric_definitions_org_key ON csuite.metric_definitions(organization_id, metric_key);

metric_samples

CREATE INDEX idx_metric_samples_org_date ON csuite.metric_samples(organization_id, sample_date);
CREATE INDEX idx_metric_samples_metric_date ON csuite.metric_samples(metric_definition_id, sample_date);

financial_transactions

CREATE INDEX idx_financial_transactions_org_date ON csuite.financial_transactions(organization_id, transaction_date);
CREATE INDEX idx_financial_transactions_type ON csuite.financial_transactions(transaction_type);

alerts

CREATE INDEX idx_alerts_org_status ON csuite.alerts(organization_id, status);
CREATE INDEX idx_alerts_created_at ON csuite.alerts(created_at);
CREATE INDEX idx_alerts_org_created ON csuite.alerts(organization_id, created_at);

action_items

CREATE INDEX idx_action_items_org_status ON csuite.action_items(organization_id, status);
CREATE INDEX idx_action_items_due_date ON csuite.action_items(due_date);
CREATE INDEX idx_action_items_org_due ON csuite.action_items(organization_id, due_date);

Banco core

core_orders

CREATE INDEX idx_core_orders_customer_date ON core.core_orders(customer_id, order_date);
CREATE INDEX idx_core_orders_status ON core.core_orders(status);
CREATE INDEX idx_core_orders_date ON core.core_orders(order_date);

core_customers

-- Já deve ter PRIMARY KEY em customer_id
CREATE INDEX idx_core_customers_email ON core.core_customers(email);
CREATE INDEX idx_core_customers_phone ON core.core_customers(phone);

core_interactions

CREATE INDEX idx_core_interactions_customer_ts ON core.core_interactions(customer_id, ts);
CREATE INDEX idx_core_interactions_ts ON core.core_interactions(ts);
CREATE INDEX idx_core_interactions_channel ON core.core_interactions(channel);

outbox_events

CREATE INDEX idx_outbox_events_type_processed ON core.outbox_events(event_type, processed);
CREATE INDEX idx_outbox_events_created_at ON core.outbox_events(created_at);
CREATE INDEX idx_outbox_events_processed_created ON core.outbox_events(processed, created_at);

Processo de Otimização

1. Análise Inicial

# Analisar banco e gerar relatório
python scripts/analyze_database_indexes.py --database csuite --config

2. Revisar Sugestões

3. Gerar SQL

# Gerar arquivo SQL com índices sugeridos
python scripts/analyze_database_indexes.py \
    --database csuite \
    --config \
    --output indexes_csuite.sql

4. Testar em Staging

# Aplicar em banco de staging primeiro
mysql -u root -p csuite_staging < indexes_csuite.sql

5. Verificar Performance

-- Antes de criar índices
EXPLAIN SELECT * FROM csuite.metric_samples 
WHERE organization_id = 1 AND sample_date >= '2024-01-01';

-- Depois de criar índices
EXPLAIN SELECT * FROM csuite.metric_samples 
WHERE organization_id = 1 AND sample_date >= '2024-01-01';

6. Aplicar em Produção

# Backup antes de aplicar
mysqldump -u root -p csuite > backup_before_indexes.sql

# Aplicar índices
mysql -u root -p csuite < indexes_csuite.sql

Monitoramento

Slow Query Log

Ative o slow query log para identificar queries que precisam de índices:

-- Verificar configuração atual
SHOW VARIABLES LIKE 'slow_query%';
SHOW VARIABLES LIKE 'long_query_time';

-- Ativar (se não estiver ativo)
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 2;  -- Log queries > 2 segundos

Analisar Slow Queries

# Ver slow queries
mysqldumpslow /var/log/mysql/slow-query.log

# Ver top 10 queries mais lentas
mysqldumpslow -s t -t 10 /var/log/mysql/slow-query.log

EXPLAIN Plan

Use EXPLAIN para verificar se índices estão sendo usados:

EXPLAIN SELECT * FROM csuite.metric_samples 
WHERE organization_id = 1 AND sample_date >= '2024-01-01';

Procure por:
- type: ref ou type: range (bom uso de índice)
- type: ALL (full table scan - precisa de índice)
- key: NULL (índice não usado)

Boas Práticas

  1. Não crie índices desnecessários: Cada índice aumenta tempo de INSERT/UPDATE
  2. Use índices compostos: Para queries com múltiplas condições WHERE
  3. Ordene colunas no índice: Coluna mais seletiva primeiro
  4. Monitore uso de índices: Remova índices não utilizados
  5. Teste em staging: Sempre teste antes de aplicar em produção
  6. Backup antes: Sempre faça backup antes de criar índices grandes

Índices Não Utilizados

Para identificar índices não utilizados:

-- Ver estatísticas de uso de índices
SELECT 
    TABLE_SCHEMA,
    TABLE_NAME,
    INDEX_NAME,
    SEQ_IN_INDEX,
    COLUMN_NAME
FROM INFORMATION_SCHEMA.STATISTICS
WHERE TABLE_SCHEMA = 'csuite'
ORDER BY TABLE_NAME, INDEX_NAME;

Troubleshooting

Índice não está sendo usado

  1. Verifique se a query usa a coluna indexada no WHERE
  2. Verifique se há funções aplicadas à coluna (ex: WHERE DATE(created_at) = ...)
  3. Verifique se há type mismatch (ex: string vs int)
  4. Use FORCE INDEX temporariamente para testar

Performance piorou após criar índice

  1. Verifique se o índice está sendo usado: EXPLAIN
  2. Considere remover o índice se não estiver ajudando
  3. Verifique se há muitos índices na tabela (pode atrasar writes)

Próximos Passos

  1. ✅ Script de análise criado
  2. ⏳ Executar análise em todos os bancos (csuite, core, staging)
  3. ⏳ Criar índices sugeridos em staging
  4. ⏳ Testar performance antes/depois
  5. ⏳ Aplicar em produção
  6. ⏳ Configurar monitoramento de slow queries
  7. ⏳ Revisar índices periodicamente (trimestral)

🔊 Text-to-Speech

1.0x
1.0
Pronto para reproduzir