Boa noite, Caros amigos gostaria de um auxilio sobre qual forma seria a melhor para se aplicar uma consulta que envolve três tabelas de banco que tem muitos registros e criar uma outra tabelas com estes dados e que não afete a performance do programa e não ocorra problemas no banco. "OBS: Isso será feito em progress caracter na versão 10.1 a" abaixo vou colocar um exemplo que me venho a cabeça para que possam me entender melhor. Código: for each tabela-a no-lock use-index usr01 by tabela-a.usr-cod, /* Aqui chutando pode se ter mais de 30.000 registros*/ /*aqui chutando para cada registro da tabela-a pode se ter mais de 150*/ each tabela-b where tabela-b.usr-cod = tabela-a.usr-cod no-lock use-index usr01 by tabela-b.usr-cod, /*aqui chutando para cada registro da tabela-b pode se ter mais de 80*/ each tabela-c where tabela-c.usr-cod = tabela-b.usr-cod no-lock use-index usr01 by tabela-c.usr-cod. create tabela-d. assign tabela-d.usr-cod = tabela-a.usr-cod tabela-d.nv-cod = tabela-b.nv-cod tabela-d.vn-cod = tabela-c.vn-cod. end. obrigado.
Não sou nenhum expert no assundo, mas presumindo que voce ja esta usando os índices corretos, acredito que a unica forma de melhorar a performance seria colocando "FIELDS" for each fazendo com que o progress traga apenas os campos que voce vai utilizar. Código: for each tabela-a fields ( usr-cod ) no-lock use-index usr01 by tabela-a.usr-cod, /* Aqui chutando pode se ter mais de 30.000 registros*/ /*aqui chutando para cada registro da tabela-a pode se ter mais de 150*/ each tabela-b fields ( usr-cod nv-cod ) where tabela-b.usr-cod = tabela-a.usr-cod no-lock use-index usr01 by tabela-b.usr-cod, /*aqui chutando para cada registro da tabela-b pode se ter mais de 80*/ each tabela-c fields ( usr-cod vn-cod ) where tabela-c.usr-cod = tabela-b.usr-cod no-lock use-index usr01 by tabela-c.usr-cod. create tabela-d. assign tabela-d.usr-cod = tabela-a.usr-cod tabela-d.nv-cod = tabela-b.nv-cod tabela-d.vn-cod = tabela-c.vn-cod. end.
Já tive uma época mexendo só com performance no Progress e descobri algumas coisas. 1. Sempre usar os índices corretos, se não tem, crie! 2. Em FOR EACH aninhados verificar se as tabelas subsequentes realmente precisa percorrer cada registro, senão use FIRST nas outras tabelas. (Isso faz uma diferença, digamos, colossal, mas tudo deve ser bem analisado, cada caso é um caso). Ex.: FOR EACH tabela-a NO-LOCK, FIRST tabela-b NO-LOCK WHERE tabela-a.id = tabela-b.id-a. [OPERAÇÕES] END. 3. Em algumas vezes forçar o uso de índice é melhor do que deixar o Progress escolher (mas isso é em raros casos). 4. Toda "declaração" no WHERE deve ser explícita, nunca usar coisas como "NOT deletado", use "deletado = FALSE", porque o Progress tem um CAST terrível fazendo com que quebre todos índices e a performance caia muuuuuiiiiiiiiiiiiiiitttttooooooooooooooo. 5. O uso do comando FIELDS, segundo a documentação, é excelente porque ele diminui o tráfego na rede e consequentemente a performance. No caso de leitura do banco (carga do HD) não percebi diferença significativa. (Analisando o tempo numa tabela com 5 milhões de registros e mais de 30 colunas) Espero ter ajudado. Abraço Rafael