DESEMPENHO DE BANCO DE DADOS - TAMANHO X DINAMISMO

THIAGO.CESAR 30/10/2011 08:07:49
#388128
Bom dia, pessoal,
Bom estar de volta após alguns anos...

Estou com um projeto em que tenho uma tabela de processos e outra onde constam parcelas de pagamentos referentes aos processos.
O processo possui um valor, e na tabela de parcelas vou incluindo linhas até totalizar o valor do processo, e possuem a seguinte estrutura:
(tabprocessos: proc_id, proc_valor...)
(tabparcelas:parc_id, parc_idprocesso, parc_valor...)

Atualmente a tabela tabprocessos possui 18.076 registros e a tabela tabparcelas possui nada menos do que 34.890 registros, e continuam crescendo...
Um dos relatórios que vou precisar preciso identificar quais processos não foram totalmente pagos. Estou usando a seguinte SQL:
SELECT tabprocessos.proc_id, (SELECT sum(tabparcelas.parc_valor) FROM tabparcelas WHERE tabparcelas.parc_idprocesso = tabprocessos.proc_id) AS total_parcelas FROM tabprocessos;

Acontece que essa consulta está consideravelmente pesada para ser executada, e a tendência é que se torne cada vez mais lenta.

Estou considerando a possibilidade de criar um campo adicional chamado proc_valor_emitido na tabela tabprocessos e atualizá-lo a cada vez que uma parcela for lançada, de modo que eu possa compará-lo sem a necessidade de executar uma soma em uma subconsulta.
Em um teste, o rendimento foi incomparavelmente melhor (de 6 segundos para menos de 1 segundo). Mas criar um campo extra me incomoda pois fica parecendo Programação Orientada a Gambiarras.

Alguém já se deparou com algo parecido? Qual foi a solução encontrada? Li alguns artigos sobre desempenho de Banco de Dados, mas nenhum deles mencionava esse dilema.

Ops! Vi que aqui embaixo tem opção para enquete . Espero respostas técnicas, mas vou deixar uma enquete também para que os companheiros que quiserem apenas registrar a opinião possam fazê-lo.

P.S.: Estou usando SQLite com php.

Abraço a todos,
LLAIA 31/10/2011 04:42:00
#388149
Cara, creio que isto vai resolver:

SELECT tabPro.proc_id,tabPro.proc_valor as ValorTotal, sum(tabParc.parc_valor) as ValorPago 
FROM tabprocessos tabPro
INNER JOIN tabparcelas tabParc ON tabPro.proc_id = tabParc.parc_idprocesso
GROUP BY tabPro.proc_id,tabPro.proc_valor
HAVING sum(tabParc.parc_valor) < tabPro.proc_valor


Também, verifique se a chave estrangeira está indexada.
MARCOSLING 31/10/2011 13:08:43
#388178
Resposta escolhida
Esse recurso de criar um campo a mais não é bem uma gambiarra...
é chamado de desnomalização de dados.
é uma técnica bastante usada (com moderação) para alcançar alta performance.

Mas, pessoalmente usaria como último recurso.
Já tentou usar stored procedure?
THIAGO.CESAR 01/11/2011 13:11:21
#388265
Obrigado LLAIA e também ao MARCOSLING pela abordagem conceitual.
Tópico encerrado , respostas não são mais permitidas