Boa tarde, pessoal. Por favor, estou precisando de dicas para otimizar um relatório, pois a sua geração está demorando muito, onde posso encontrar? Já me passaram uma dica para incluir "no-lock" em todos os "for each", após fazer essa inclusão a geração do relatório passou de 25 para 21 minutos. Aguardo e agradeço. Fábia
Fábia, boa tarde !! Você "manja" de Index? Pode ser que seu problema seja ìndices, devido a demorar tanto tempo, 20 minutos é muito tempo esperando um relatório, quase inadimissível! Geralmente as tabelas possuem índices, que servem justamente para facilitar as coisas na hora do SGDB recuperar as informações guardadas. Então você precisa conhecer os índices das tabelas que você está trabalhando/pesquisando(for each) para puder satisfazer o máximo possível dos ìndices exsitentes. Pra Conhcer os índices vá no seu Banco de Dados/Data Administration , Primeira opção , DataBase/ Reports/Quick Indexs Irá abrir a lista de tabelas do seu banco, então vc seleciona a que vc quer estudar, e veja quais os índeces que existem. COnhecendo os Índeces, Tipo , lá no For Each vc estava Fazendo Assim FOR EACH Receber NO-LOCK, dái vc viu que o CNPJ era um índice da tabela Receber, entao vc pode fazer o seguinte, FOR EACH Clientes-Fornecedores WHERE CLientes-Fornecedores.Ativo.... Dentro deste For EAch vc teria vários CNPJ's que poderia usar no For each Receber. por Ex. Código: FOR EACH Clientes WHERE Clientes.Ativo AND CLientes.Condicao_pagto > 0 NO-LOCK. FOR EACH Receber WHERE Receber.CNPJ = Clientes.CNPJ NO-LOCK. END. END. Então antes vc não satisfazia nenhum índice, e agora já satisfaz um, por exemplo. deu pra entender +- ?
Experiências com Melhoria de Performance Bom dia, Compartilhando minhas experiências em melhoria de performance, encontrei várias maneiras de melhorar a Performance. 1º) Use índice (Nunca em Excesso), com exatamente os campos que você está usando na condição (WHERE) da QUERY. Exemplo: - Índice IDX01 com os campos: nr-ord-produ (ASC), it-codigo(ASC) No FIND para forçar o índice: Código: FIND FIRST ord-prod WHERE ord-prod.nr-ord-produ = 12345 AND it-codigo = "AAABBBCCC" NO-LOCK NO-ERROR USE-INDEX IDX01. No FOR: Código: FOR EACH ord-prod NO-LOCK WHERE ord-prod.nr-ord-produ = 12345 AND it-codigo = "AAABBBCCC" USE-INDEX IDX01. [CÓDIGO]. END. 2º) SEMPRE UTILIZE CONDIÇÃO EXPLÍCITA: No WHERE da QUERY nunca utilize em campos lógicos (LOGICAL) o "NOT" antes da variável, sempre use "= FALSE". E também em variáveis que precisa ser TRUE, deixe "= TRUE" explícito. Isso acontece porque o NOT antes força o banco fazer CAST de todos os registros, levando mais que o dobro do tempo. Certa vez, num programa consegui diminuir o tempo de mais de 5 minutos para instantâneo a operação, só fazendo essa operação sem mexer em índice. Exemplo: Código: FIND FIRST clientes WHERE NOT clientes.ativo NO-LOCK NO-ERROR. (ERRADO!) FIRST clientes WHERE clientes.ativo = FALSE NO-LOCK NO-ERROR. (CERTO!) FIRST clientes WHERE clientes.ativo NO-LOCK NO-ERROR. (ERRADO!) FIRST clientes WHERE clientes.ativo = TRUE NO-LOCK NO-ERROR. (CERTO!) 3º) LIMITE A QUERY: Na condição da Query, ajuste bem de forma a carregar somente os registros que interessam. Exemplo: Código: FOR EACH pesagem NO-LOCK. (ERRADO!) END. FOR EACH pesagem NO-LOCK WHERE ord-prod.nr-ord-prod = 123456. (CERTO!) END. 4º) Deixe explícito o nome do banco e da tabela na query e nas atribuições (ASSIGN), isso evita vários erros (em casos de tabelas com mesmo nome em bancos diferentes) evitando assim verificações adicionais do banco. Exemplo.: Código: FOR EACH movind.ord-prod WHERE movind.ord-prod.nr-ord-prod = 123456. ASSIGN movind.ord-prod.campo-qualquer = "TESTE". END. Até o momento, de todos os testes que fiz, isso deixou quase 100% performático, operações quase que Instantâneas. Poste aqui o resultado de como ficou a performance do relatório. Espero ter ajudado. Att, Rafael