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:
- Foreign Keys: Todas as colunas que são chaves estrangeiras
organization_id,org_idcustomer_iduser_id-
Qualquer coluna terminando em
_id -
Timestamps para Filtros: Colunas de data usadas em WHERE
created_atupdated_atdeleted_at-
Qualquer coluna com
_dateoudate -
Índices Compostos Comuns:
(organization_id, created_at)- Filtro por org + data(customer_id, status)- Filtro por cliente + status(organization_id, enabled, created_at)- Filtro complexo comum
Índices de Média Prioridade
Estes índices melhoram performance mas não são críticos:
- Status Flags: Colunas booleanas usadas em filtros
enabledactivedeleted-
status -
Lookup Fields: Campos usados para busca
emailphonenamekey,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
- Verifique se as sugestões fazem sentido para seu caso de uso
- Priorize índices de alta prioridade
- Considere o impacto em writes (índices aumentam tempo de INSERT/UPDATE)
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
- Não crie índices desnecessários: Cada índice aumenta tempo de INSERT/UPDATE
- Use índices compostos: Para queries com múltiplas condições WHERE
- Ordene colunas no índice: Coluna mais seletiva primeiro
- Monitore uso de índices: Remova índices não utilizados
- Teste em staging: Sempre teste antes de aplicar em produção
- 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
- Verifique se a query usa a coluna indexada no WHERE
- Verifique se há funções aplicadas à coluna (ex:
WHERE DATE(created_at) = ...) - Verifique se há type mismatch (ex: string vs int)
- Use
FORCE INDEXtemporariamente para testar
Performance piorou após criar índice
- Verifique se o índice está sendo usado:
EXPLAIN - Considere remover o índice se não estiver ajudando
- Verifique se há muitos índices na tabela (pode atrasar writes)
Próximos Passos
- ✅ Script de análise criado
- ⏳ Executar análise em todos os bancos (csuite, core, staging)
- ⏳ Criar índices sugeridos em staging
- ⏳ Testar performance antes/depois
- ⏳ Aplicar em produção
- ⏳ Configurar monitoramento de slow queries
- ⏳ Revisar índices periodicamente (trimestral)