Jump to content
Fivewin Brasil

COMANDO EM SQL DEMORANDO DEMIAS QUANDO A BASE É GRABDE


marcioe

Recommended Posts

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

xxxxxxxxxxxxxxxxxxxxx.jpg?1616626188

Quem Puder ajudar fico Grato

 

 


 

Link to comment
Share on other sites

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.

 

"

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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 

 

 

 

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...