ActiveDelphi - Índice do Fórum ActiveDelphi
.: O site do programador Delphi! :.
 
 FAQFAQ   PesquisarPesquisar   MembrosMembros   GruposGrupos   RegistrarRegistrar 
 PerfilPerfil   Entrar e ver Mensagens ParticularesEntrar e ver Mensagens Particulares   EntrarEntrar 

Melhorar a performance do select lento?

 
Novo Tópico   Responder Mensagem    ActiveDelphi - Índice do Fórum -> Banco de Dados
Exibir mensagem anterior :: Exibir próxima mensagem  
Autor Mensagem
adriano_servitec
Colaborador
Colaborador


Registrado: Sexta-Feira, 30 de Janeiro de 2004
Mensagens: 17618

MensagemEnviada: Qua Abr 10, 2019 11:08 am    Assunto: Melhorar a performance do select lento? Responder com Citação

Uso firebird 2.5 e tenho um select muito lento

Código:
SELECT Coalesce(CL.CODIGO, RV.CODIGO) AS COD_CLIENTE,
       fc.BOLETO_JUROS_ULTIMO_RETORNO,
       FC.CODIGO AS COD_CONTA,
       Coalesce(FC.CODIGO_CLIENTE, FC.CODIGO_REVENDA) CodSac,
       FC.TIPO_SACADO,

  (SELECT numero
   FROM extrai_numero(Coalesce(CL.INSCRICAO_ESTADUAL, RV.INSCRICAO_ESTADUAL))) AS INSCRICAO_ESTADUAL,
       FC.DESCRICAO,
       FC.DATA_QUITACAO,
       NOTA_RPS_VALOR_BASE,
       fc.BOLETO_VALOR_PAGO,

  (SELECT numero
   FROM extrai_numero(Coalesce(CL.cnpj, RV.cnpj))) AS CNPJ,
       Coalesce(CL.NOME_BOLETO, Coalesce(RV.NOME_BOLETO, RV.Nome)) NOME,
       FC.DISCRIMINACAO_SERVICO,
       Coalesce(CL.CIDADE, RV.CIDADE) Cidade,
       BOLETO_DESCONTO_ULTIMO_RETORNO,
       Coalesce(CL.CIDADE_BOLETO, RV.CIDADE_BOLETO) CIDADE_BOLETO,
       Coalesce(CL.ENDERECO_BOLETO, RV.ENDERECO_BOLETO) Endereco_Boleto,
       Coalesce(CL.BAIRRO, RV.BAIRRO) Bairro,
       UPPER(TRATAACENTOS(Coalesce(CL.CIDADE, RV.CIDADE))),
       Coalesce(CL.ESTADO_BOLETO, RV.ESTADO_BOLETO) ESTADO_BOLETO,
       ES.SIGLA,
       FC.NOTA_RPS_LOTE,
       CASE
           WHEN ES.SIGLA='DF' THEN '5300108'
           ELSE MU.CODIGO_IBGE
       END CODIGO_IBGE,
       MU.CODIGO_IBGE,
       CASE
           WHEN fc.nota_ConfirmadoEnvio='S' THEN 'Sim'
           ELSE 'Não'
       END RetornoOK,
       CASE
           WHEN FC.NOTA_RPS IS NULL THEN 'Não'
           ELSE 'Sim'
       END Enviado,
       Coalesce(CL.CEP_BOLETO, RV.CEP_BOLETO) CEP_BOLETO,
       FC.DATA_VENCIMENTO,
       CASE FC.TIPO_SACADO
           WHEN 'Cliente' THEN Coalesce(CL.SIMPLES_NACIONAL, 'Não')
           WHEN 'Revenda' THEN Coalesce(RV.SIMPLES_NACIONAL, 'Não')
       END SIMPLES_NACIONAL,
       FC.NOTA_RPS,
       FC.NOTA_NFSE,
       FC.VALOR valor_conta,
       fc.nota_rps_valor_base AS valor,
       fc.NOTA_RPS_PIS AS PIS,
       FC.NOTA_RPS_LOTE LOTE,
       fc.NOTA_RPS_DATA_EMISSAO,
       fc.NOTA_RPS_COFINS AS COFINS,
       fc.NOTA_RPS_CSLL AS CSLL,
       fc.NOTA_RPS_IR AS IR,
       fc.NOTA_RPS_ISS_RET AS ISS,
       CL.RETER_ISS,
       CL.RETER_ISS_PERC,
       h.pis_nota,
       h.cofins_nota,
       h.csll_nota,
       h.ir_nota,
       h.iss_nota,
       h.NUMERO_NOTA,
       (FC.nota_rps_valor_base * 0.1345) AS TOTAL_TRIBUTOS,

  (SELECT numero_nota
   FROM historico_notas_geradas hng
   WHERE hng.id = fc.id_historico) AS nfse
FROM FINANCEIRO_CONTAS FC
LEFT JOIN CLIENTE CL ON CL.CODIGO = FC.CODIGO_CLIENTE
AND FC.tipo_sacado='Cliente'
LEFT JOIN REVENDAS RV ON RV.CODIGO = FC.CODIGO_REVENDA
AND FC.tipo_sacado='Revenda'
LEFT JOIN ESTADOS ES ON (CL.ESTADO = ES.NOME
                         AND CL.ESTADO IS NOT NULL)
OR (RV.ESTADO = ES.NOME
    AND RV.ESTADO IS NOT NULL)
LEFT JOIN historico_notas_geradas h ON fc.codigo = h.cod_conta_vinculada_sistema
LEFT JOIN MUNICIPIOS MU ON (MU.UF = ES.SIGLA
                            AND CL.CIDADE IS NOT NULL
                            AND UPPER(TRATAACENTOS(MU.MUNICIPIO)) = UPPER(TRATAACENTOS(CL.CIDADE)))
OR (MU.UF = ES.SIGLA
    AND RV.CIDADE IS NOT NULL
    AND UPPER(TRATAACENTOS(MU.MUNICIPIO)) = UPPER(TRATAACENTOS(RV.CIDADE)))
WHERE (FC.nota_rps_data_emissao BETWEEN :DATA_INI AND :DATA_FIM
       AND FC.CANCELADO <> 'Sim')
  AND ((FC.BOLETO_STATUS = 'Retorno Processado'
        AND BOLETO = 'Sim'
        AND BOLETO_MODALIDADE IN ('Simples',
                                  'Descontada'))
       OR (FC.descricao = 'Deposito'
           AND FC.centro_custos = '01.001.003.001')
       OR (FC.descricao = 'Dinheiro'
           AND FC.centro_custos = '01.001.002.001.001'))
  AND h.data_emissao_nota BETWEEN :DATA_INI AND :DATA_FIM
ORDER BY
  h.data_emissao_nota, h.numero_nota


Tem como melhorar a performance dele pra ficar mais rápido?

Obrigado.
_________________
Jogo seu smartphone? Acesse o link e confira.
https://play.google.com/store/apps/details?id=br.com.couldsys.rockdrum
https://play.google.com/store/apps/details?id=br.com.couldsys.drumsetfree
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
Cleriton
Novato
Novato


Registrado: Quarta-Feira, 28 de Janeiro de 2009
Mensagens: 59
Localização: São José do Rio Preto / SP

MensagemEnviada: Qui Abr 11, 2019 12:06 pm    Assunto: Responder com Citação

Duas sugestões que podem ajudar muito no desempenho.

1ª Sugestão: Seria fragmentar esse select em partes menores e depois unificar os dados logicamente dentro da aplicação, tirando a responsabilidade do servidor de dados.

2ª Sugestão: Indexar os registros das tabelas envolvidas de acordo com os filtros efetuados.
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular Enviar E-mail MSN Messenger
joemil
Moderador
Moderador


Registrado: Quinta-Feira, 25 de Março de 2004
Mensagens: 9100
Localização: Sinop-MT

MensagemEnviada: Qui Abr 11, 2019 3:09 pm    Assunto: Responder com Citação

tem necessidade desses subselects?

no MySQL, temos o comando EXPLAIN, q da os dados de performance e uso de indices:

EXPLAIN SELECT ....

veja se no seu banco tem esse comando, e se é facil pra entender, pq no Postgre é complicado de ler rsrsrs
_________________
<b>SEMPRE COLOQUE [RESOLVIDO] NO SEU POST</b>
Enviar imagens: http://tinypic.com/
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
adriano_servitec
Colaborador
Colaborador


Registrado: Sexta-Feira, 30 de Janeiro de 2004
Mensagens: 17618

MensagemEnviada: Ter Abr 23, 2019 10:02 am    Assunto: Responder com Citação

Obrigado pela resposta pessoal

Outra duvida

Neste caso qual seria o melhor SQL

Assim
Código:

SELECT Cd_Recebimento,
       Nome_Cliente,
       Vl_Devido,
       Vl_Pago,
       Dt_vencimento,
       Dt_Pagamento
FROM ContasReceber A,
     Clientes C,
     Agenciadores E
WHERE A.Cd_Convenio_Recebimento > 0
  AND A.Cd_Situacao_Pagamento IN (20)
  AND A.Cd_Cliente = C.Cd_Cliente
  AND E.cd_agenciador = A.Cd_Agenciador
  AND A.Ano_Base = 2019
  AND A.Mes_Base = 1


Ou assim
Código:
SELECT Cd_Recebimento,
       Nome_Cliente,
       Vl_Devido,
       Vl_Pago,
       Dt_vencimento,
       Dt_Pagamento
FROM ContasReceber A

INNER JOIN CLIENTES C ON  A.Cd_Cliente = C.Cd_Cliente
INNER JOIN agenciadores e ON  E.cd_agenciador = A.Cd_Agenciador

WHERE A.Cd_Convenio_Recebimento > 0
  AND A.Cd_Situacao_Pagamento IN (20)
  AND A.Ano_Base = 2019
  AND A.Mes_Base = 1


Existe algum ganho em uso de JOIN ou não muda nada?
_________________
Jogo seu smartphone? Acesse o link e confira.
https://play.google.com/store/apps/details?id=br.com.couldsys.rockdrum
https://play.google.com/store/apps/details?id=br.com.couldsys.drumsetfree
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
imex
Moderador
Moderador


Registrado: Sexta-Feira, 7 de Janeiro de 2011
Mensagens: 11666

MensagemEnviada: Ter Abr 23, 2019 11:39 am    Assunto: Responder com Citação

Bom dia,

Nunca fiz nenhum teste mas as recomendações que costumo ver nesse caso são para uso da sintaxe com Join.
Parece que alguns bancos de dados otimizam a sintaxe antes da execução, transformando a sintaxe sem Join para a com Join, o que acaba deixando o desempenho igual.
Desempenho a parte, a sintaxe com Join facilita a análise da instrução SQL.

Espero que ajude


Editado pela última vez por imex em Seg Set 20, 2021 10:12 am, num total de 1 vez
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
adriano_servitec
Colaborador
Colaborador


Registrado: Sexta-Feira, 30 de Janeiro de 2004
Mensagens: 17618

MensagemEnviada: Ter Abr 23, 2019 11:57 am    Assunto: Responder com Citação

imex escreveu:
Bom dia,

Nunca fiz nenhum teste mas as recomendações que costumo ver nesse caso são para uso da sintaxe com Join.
Parece que alguns bancos de dados otimizam a sintaxe antes da execução, transformando a sintaxe sem Join para a com Join, o que acaba deixando o desempenho igual.
Desempenho a parte, a sintaxe com Join facilita a análise da instrução SQL.

Espero que ajude


Muito obrigado pela explicação.
_________________
Jogo seu smartphone? Acesse o link e confira.
https://play.google.com/store/apps/details?id=br.com.couldsys.rockdrum
https://play.google.com/store/apps/details?id=br.com.couldsys.drumsetfree
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
Mostrar os tópicos anteriores:   
Novo Tópico   Responder Mensagem    ActiveDelphi - Índice do Fórum -> Banco de Dados Todos os horários são GMT - 3 Horas
Página 1 de 1

 
Ir para:  
Enviar Mensagens Novas: Proibido.
Responder Tópicos Proibido
Editar Mensagens: Proibido.
Excluir Mensagens: Proibido.
Votar em Enquetes: Proibido.


Powered by phpBB © 2001, 2005 phpBB Group
Traduzido por: Suporte phpBB