marcioe Posted March 24, 2021 Report Share Posted March 24, 2021 Olá, boa noite Estou com um problema para realizar uma consulta SQL Quando o tem poucos registros tipo 100.000 registos até que vai. Porem temos uma empresa que tem uma tabela de aprox. 4.000.000.000 quatro milhoes Ai o servidor demora demais a responder O comando é esse SELECT (t_nf_saida.NUMERO_PEDIDO+t_nf_saida.NUMERO_CARGA) AS NUMERO_CAB, (vendas.NUMVEN+ vendas.NUMERO_CARGA) AS NUMERO_DET, t_nf_saida.*, clientes.CLINOM, clientes.CLIEST, clientes.CLICPF, clientes.CLIREG, retornos_sefaz.DESCRICAO AS retornos_sefaz_DESCRICAO, IF(t_nf_saida.STATUS_SEFAZ ="100",sum( CAST(vendas.TOTVEN AS DECIMAL(18,2))),0) as VALOR_BRUTO_SAIDA, IF(t_nf_saida.STATUS_SEFAZ ="100",sum(CAST(vendas.TOTVEN-(vendas.DESVEN+vendas.DESCONTO_NOTA_FISCAL) AS DECIMAL(18,2))) ,0) as VALOR_CONTABIL_SAIDA, IF(t_nf_saida.STATUS_SEFAZ ="100",sum(CAST(vendas.DESVEN+vendas.DESCONTO_NOTA_FISCAL AS DECIMAL(18,2))),0) as VALOR_DESCONTO_SAIDA, IF(t_nf_saida.STATUS_SEFAZ ="100",sum(CAST(vendas.DESPESAS_ACESSORIAS AS DECIMAL(18,2))),0) as VALOR_DESPESAS_ACESSORIAS, if(vendas.VALOR_ICMS!=0,sum(vendas.BASE_ICMS),0) AS B_CALCULO, CAST(vendas.ALIQUOTA_ICMS AS DECIMAL(18,2)) AS ALIQUOTA_CREDITO_ICMS, sum(CAST(vendas.VALOR_ICMS AS DECIMAL(18,2))) AS VALOR_ICMS, sum(CAST(vendas.VALOR_ICMS_ST AS DECIMAL(18,2))) AS VALOR_ICMS_ST, sum(CAST(vendas.VALOR_IPI AS DECIMAL(18,2))) AS VALOR_IPI, vendas.CFOP as vendas_CFOP, "ICMS" FROM t_nf_saida AS t_nf_saida LEFT JOIN clientes AS clientes ON clientes.CLICOD = t_nf_saida.CODIGO_CLIENTE LEFT JOIN retornos_sefaz AS retornos_sefaz ON retornos_sefaz.CODIGO = t_nf_saida.STATUS_SEFAZ LEFT JOIN vendas AS vendas ON (t_nf_saida.NUMERO_PEDIDO+t_nf_saida.NUMERO_CARGA) = (vendas.NUMVEN+ vendas.NUMERO_CARGA) AND t_nf_saida.NUMERO_NF != ' 0' AND t_nf_saida.MODELO_DOCUMENTO != ' ' AND t_nf_saida.SERIE_NF != ' ' AND t_nf_saida.INULTILIZADA != 'S' GROUP BY t_nf_saida.ID ORDER BY t_nf_saida.NUMERO_NF,t_nf_saida.MODELO_DOCUMENTO,t_nf_saida.SERIE_NF, vendas.CFOP Acredito que possa ser mais Rápido que está no momento. Rodei o com o comando DESC ou com o comando explain e o resultado foi Quem Puder ajudar fico Grato Quote Link to comment Share on other sites More sharing options...
alex2002 Posted March 25, 2021 Report Share Posted March 25, 2021 Olá Márcio, Vc teria que ter um índice bem apropriado na tabela vendas. Isso irá ajudar muito em termos de velocidade. Um abraço, Alexandre Pereira Quote Link to comment Share on other sites More sharing options...
marcioe Posted March 25, 2021 Author Report Share Posted March 25, 2021 Top, amigo, mas mesmo com indices está demorando, Quote Link to comment Share on other sites More sharing options...
emotta Posted March 27, 2021 Report Share Posted March 27, 2021 Márcio aconselho vc a assistir a série de videos "O SQL é extremamente rápido vc que não sabe usar" Estou postando o primeiro mas a série tem 4 vídeos e estão fazendo um quinto. Assisti todos e me ajudou muito a entender como o SQL "pensa" ao resolver os selects pra gente. Vale muito a pena, te garanto. Após assistir vc mesmo vai conseguir identificar o que está fazendo errado. Apesar de ser focado em SQL server muito dicas serve pra qq banco de dados. " Quote Link to comment Share on other sites More sharing options...
emotta Posted March 28, 2021 Report Share Posted March 28, 2021 O que está matando o SQL são esses IFs e os CASTs Também não estou vendo WHERE Vc precisa mesmo passar por todos os 4 milhões de registros? Como estou vendo este tópico pelo celular posso não ter visto algo, mas ao bater o olho vi essas coisas. Quando puder veja os vídeos que vai te ajudar. Quote Link to comment Share on other sites More sharing options...
marcioe Posted March 30, 2021 Author Report Share Posted March 30, 2021 Olá a todos, Primeiro muito obrigado por responderem A solução que fiz, pode não ser a melhor técnica, mas a principio resolveu, nesse caso o relatorio não era gerado, travava o PC, etc... Fiz assim Na tabela de vendas criei um campo chamado ID_CABECALHO_DFE, indexado e que faz ligação com a tabela T_NF_SAIDA que é o cabeçalho das notas FILTRO O CABECALHO DAS NOTAS FISCAIS, NO PERIODO DESEJADO, FAÇO UM LAÇO E GRAVO NA TABELA DE VENDAS O ID DO CABECALHO. LOGO APOS CRIO UMA TABELA TEMPORARIA UNINDO O CABECALHO EM RESUMO O MUSQL PASSARA A UNIR 10.000 REG COM UNS 30.000 REG. O QUE LEVA UNS 7 SEG. DEPOIS FAÇO O FILTRO COM OS SUM, IF TUDO BASEADO NESSA TABELA TEMPORARIA. EM RESUMO DEMORA UNS 30 A 40 SEGUNDO O PROCESSAMENTO DO INICIO AO FINAL. (EM UMA BASE COM MAIS 4.000.000.000 quatro milhoes) É BEM ACEITAVEL PODE SER QUE NÃO SEJA A MELHOR TECNICA, MAS FUNCINOU. ESTOU ABERTO A NOVAS IDEIAS. DE QUALQUER FORMA POSTEI, POIS PODE SER QUE TENHA COMO MELHORAR. AGORA EU VOU DAR UMA REDUZIDA NESSE CÓDIGO E REMOVER ALGUNS LIXOS. *------------------------------------------------------------------------------- * Funcao Usada para Gerar Livro de Registro de Saida e Sintegra *------------------------------------------------------------------------------- FUNCTION FILTRA_REGISTRO_SAIDA_CABECALHO(v_Perido_Inicial, v_Periodo_Final, v_Tipo_Livro, v_Suprime_Inutilizada, v_Status, v_Codigo_Serie_Documento, v_Agrupamento, v_ordenacao, v_Imprime_Livro, v_Codigo_Cliente, v_Agrupamento_Detalhe, v_Ordenacao_Detalhe, v_Numero_Dfe, v_Item_Marcado) Cursor('SQL') *---------------------------------------------------------------------------- * Se Houver Vendas Com o Id do DF-e *---------------------------------------------------------------------------- IF SELECT("t_nf_saida") != 0 t_nf_saida->(DbCloseArea()) ENDIF cQuery:= " SELECT t_nf_saida.NUMERO_PEDIDO, t_nf_saida.NUMERO_CARGA, t_nf_saida.ID, t_nf_saida.DATA_EMISSAO " cQuery:=cQuery + " FROM t_nf_saida AS t_nf_saida " cQuery:=cQuery + " WHERE t_nf_saida.DATA_EMISSAO BETWEEN " + TRANSFORMA_SQL(v_Perido_Inicial,'D',08,0) + " AND " + TRANSFORMA_SQL(v_Periodo_Final,'D',08,0) cQuery:=cQuery + " ORDER BY t_nf_saida.DATA_EMISSAO, t_nf_saida.NUMERO_NF, t_nf_saida.MODELO_DOCUMENTO " use sql cQuery alias "t_nf_saida" new via 'MYSQL' t_nf_saida->( DbGoTop()) DO WHILE t_nf_saida->( !EOF()) Cursor('sql') DbSelectArea('t_nf_saida') IF t_nf_saida->NUMERO_PEDIDO+t_nf_saida->NUMERO_CARGA != 0 BEGIN TRANSACTION cQuery_Mtabela := 'update vendas SET ID_CABECALHO_DFE = ' + TRANSFORMA_SQL(t_nf_saida->ID,'N',11,0) + ' WHERE ' IF t_nf_saida->NUMERO_PEDIDO != 0 cQuery_Mtabela := cQuery_Mtabela + ' NUMVEN = ' + TRANSFORMA_SQL(t_nf_saida->NUMERO_PEDIDO,'N',11,0) ELSE cQuery_Mtabela := cQuery_Mtabela + ' NUMERO_CARGA = ' + TRANSFORMA_SQL(t_nf_saida->NUMERO_CARGA,'N',11,0) ENDIF cQuery_Mtabela := cQuery_Mtabela + ' AND MARCADO = ' + TRANSFORMA_SQL( 'S','T',01,0) sql execute( cQuery_Mtabela ) END TRANSACTION ENDIF CursorArrow() t_nf_saida->(dbSkip()) ENDDO SQL EXECUTE('COMMIT') IF SELECT("t_nf_saida") != 0 t_nf_saida->(DbCloseArea()) ENDIF *---------------------------------------------------------------------------- BEGIN TRANSACTION cCMDSQL := " CREATE TEMPORARY TABLE tmp_vendas " cCMDSQL := cCMDSQL + " SELECT vendas.* , " cCMDSQL := cCMDSQL + " t_nf_saida.DATA_EMISSAO, t_nf_saida.NUMERO_NF, t_nf_saida.SERIE_NF, t_nf_saida.MODELO_DOCUMENTO " cCMDSQL := cCMDSQL + " from vendas as vendas " cCMDSQL := cCMDSQL + " LEFT JOIN t_nf_saida AS t_nf_saida ON t_nf_saida.ID = vendas.ID_CABECALHO_DFE " cCMDSQL := cCMDSQL + " where vendas.ID_CABECALHO_DFE != 0 " cCMDSQL := cCMDSQL + " ORDER BY t_nf_saida.NUMERO_NF, t_nf_saida.MODELO_DOCUMENTO " SqlExecute( cCMDSQL ) END TRANSACTION *---------------------------------------------------------------------------- Cursor('sql') IF SELECT("registro_saida") != 0 registro_saida->(DbCloseArea()) ENDIF cQuery:= ' SELECT t_nf_saida.*, ' cQuery:=cQuery +' clientes.CLINOM, clientes.CLIEST, clientes.CLICPF, clientes.CLIREG, ' cQuery:=cQuery +' retornos_sefaz.DESCRICAO AS retornos_sefaz_DESCRICAO, ' cQuery:=cQuery +' IF(t_nf_saida.STATUS_SEFAZ ="100",sum( CAST(vendas.TOTVEN AS DECIMAL(18,2))),0) as VALOR_BRUTO_SAIDA, ' cQuery:=cQuery +' IF(t_nf_saida.STATUS_SEFAZ ="100",sum(CAST(vendas.TOTVEN-(vendas.DESVEN+vendas.DESCONTO_NOTA_FISCAL) AS DECIMAL(18,2))) ,0) as VALOR_CONTABIL_SAIDA, ' cQuery:=cQuery +' IF(t_nf_saida.STATUS_SEFAZ ="100",sum(CAST(vendas.DESVEN+vendas.DESCONTO_NOTA_FISCAL AS DECIMAL(18,2))),0) as VALOR_DESCONTO_SAIDA, ' cQuery:=cQuery +' IF(t_nf_saida.STATUS_SEFAZ ="100",sum(CAST(vendas.DESPESAS_ACESSORIAS AS DECIMAL(18,2))),0) as VALOR_DESPESAS_ACESSORIAS, ' cQuery:=cQuery +' if(vendas.VALOR_ICMS!=0,sum(vendas.BASE_ICMS),0) AS B_CALCULO, ' cQuery:=cQuery +' CAST(vendas.ALIQUOTA_ICMS AS DECIMAL(18,2)) AS ALIQUOTA_CREDITO_ICMS, ' cQuery:=cQuery +' sum(CAST(vendas.VALOR_ICMS AS DECIMAL(18,2))) AS VALOR_ICMS, ' cQuery:=cQuery +' sum(CAST(vendas.VALOR_ICMS_ST AS DECIMAL(18,2))) AS VALOR_ICMS_ST, ' cQuery:=cQuery +' sum(CAST(vendas.VALOR_IPI AS DECIMAL(18,2))) AS VALOR_IPI, ' cQuery:=cQuery +' vendas.CFOP as vendas_CFOP, "ICMS" ' cQuery:=cQuery +' FROM t_nf_saida AS t_nf_saida ' cQuery:=cQuery +' LEFT JOIN clientes AS clientes ON clientes.CLICOD = t_nf_saida.CODIGO_CLIENTE ' cQuery:=cQuery +' LEFT JOIN retornos_sefaz AS retornos_sefaz ON retornos_sefaz.CODIGO = t_nf_saida.STATUS_SEFAZ ' *cQuery:=cQuery +' LEFT JOIN vendas AS vendas ON if(t_nf_saida.NUMERO_PEDIDO!=0,vendas.NUMVEN,vendas.NUMERO_CARGA) = if(t_nf_saida.NUMERO_PEDIDO!=0,t_nf_saida.NUMERO_PEDIDO,t_nf_saida.NUMERO_CARGA) ' cQuery:=cQuery +' LEFT JOIN tmp_vendas AS vendas ON vendas.ID_CABECALHO_DFE = t_nf_saida.ID ' cQuery:=cQuery +' WHERE t_nf_saida.DATA_EMISSAO BETWEEN ' + TRANSFORMA_SQL(v_Perido_Inicial,'D',08,0) + ' AND ' + TRANSFORMA_SQL(v_Periodo_Final,'D',08,0) cQuery:=cQuery +' AND t_nf_saida.NUMERO_NF != ' + TRANSFORMA_SQL(0,'N',10,0) cQuery:=cQuery +' AND t_nf_saida.MODELO_DOCUMENTO != ' + TRANSFORMA_SQL('','T',02,0) cQuery:=cQuery +' AND t_nf_saida.SERIE_NF != ' + TRANSFORMA_SQL('','T',02,0) IF ALLTRIM(v_Item_Marcado) = 'S' cQuery:=cQuery +' AND vendas.MARCADO = ' + TRANSFORMA_SQL( 'S','T',01,0) ENDIF *---------------------------------------------------------------------------- * Se Irá Suprimir Inutilizada *---------------------------------------------------------------------------- IF ALLTRIM(v_Suprime_Inutilizada) = 'S' cQuery:=cQuery +' AND t_nf_saida.INULTILIZADA != ' + TRANSFORMA_SQL("S","T",01,0) ENDIF *---------------------------------------------------------------------------- * Se for Só de Um status *---------------------------------------------------------------------------- IF !EMPTY(ALLTRIM(v_Status)) cQuery:=cQuery +' AND t_nf_saida.STATUS_SEFAZ = ' + TRANSFORMA_SQL(v_Status,'T',03,0) ENDIF *---------------------------------------------------------------------------- * Se for Só de um Código de Documento / Serie *---------------------------------------------------------------------------- IF !EMPTY(ALLTRIM(v_Codigo_Serie_Documento)) cQuery:= cQuery + ' AND t_nf_saida.MODELO_DOCUMENTO = ' + TRANSFORMA_SQL(SUBSTR(v_Codigo_Serie_Documento,01,02),'T',02,0) cQuery:= cQuery + ' AND t_nf_saida.SERIE_NF = ' + TRANSFORMA_SQL(SUBSTR(v_Codigo_Serie_Documento,04,03),'T',03,0) ENDIF *---------------------------------------------------------------------------- IF v_Codigo_Cliente != 0 cQuery := cQuery + ' AND clientes.CLICOD = ' + TRANSFORMA_SQL( v_Codigo_Cliente,'N',06,0 ) ENDIF *---------------------------------------------------------------------------- IF !EMPTY(ALLTRIM(v_Agrupamento)) cQuery:=cQuery +' GROUP BY ' + ALLTRIM(v_Agrupamento) ENDIF *---------------------------------------------------------------------------- IF !EMPTY(ALLTRIM(v_Ordenacao)) cQuery:=cQuery +' ORDER BY ' + ALLTRIM(v_ordenacao) ENDIF ***MemoEdit(cQuery) use sql cQuery alias "registro_saida" new via 'MYSQL' registro_saida->( DbGoTop()) *---------------------------------------------------------------------------- RETURN Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.