none
Optimização de procedure RRS feed

  • Pergunta

  • Olá a todos,

    estou realizando um procedure de carga.

    O problema que estou enfrentando e que a procedure está levando muito tempo para executar. Gostaria de pedir ajuda para que os senhores pudessem me direcionar onde devo alterar o sql ou se existe metodos mais eficazes.

    Basicamente ela procura uma quantidade de lotes especificos e agrupa em uma temp, depois preciso agrupar os lotes por data para realizar o cálculo.

    Utilizo três funções:

    - ano_referencia que procura o ultimo dia util do mes anterior do ano anterior

    -data_referencia que procura o ultimo dia util do mes anterior

    -data_seguinte que adiciona uma data util

    • Editado Rafael R Santos terça-feira, 11 de dezembro de 2012 21:21 A página estava ficando muito grande
    sexta-feira, 7 de dezembro de 2012 20:09

Respostas

  • Rafael,

    Teoricamente não é para ficar mais lento, ao contrário você estaria dividindo a carga de trabalho em processamentos paralelos.

    Em relação as tabelas é possível sim criar uma temporária a outras procedures ou sessões utilizarem, mas para isso terá que ser uma table temporária global e não local.

    Vale ressaltar que toda tabela temporária global vai existir enquanto a conexão do usuário na instância do SQL Server estiver em uso e ativa.


    Pedro Antonio Galvão Junior [MVP | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados | SorBR.Net | Professor Universitário | MSIT.com]

    • Marcado como Resposta Rafael R Santos segunda-feira, 10 de dezembro de 2012 18:34
    segunda-feira, 10 de dezembro de 2012 17:54
  • Olá Rafael,

    A primeira coisa que você deve fazer é eliminar o uso de cursores na procedure. 

    Abraço


    MCP – MCTS – MCITP – MCT SQL Server ADM / BI / Dev Sharepoint IBM Optim Certification http://demetriosilva.wordpress.com/

    • Marcado como Resposta Rafael R Santos terça-feira, 11 de dezembro de 2012 16:10
    terça-feira, 11 de dezembro de 2012 14:15

Todas as Respostas

  • Rafael,

    Realmente a Procedure é bem extensa o que acaba tornando impossível o entendimento.

    Uma pergunta, você já tentou dividir esta procedure em outras pequenas procedures e fazer a chamada uma dentro da outra?


    Pedro Antonio Galvão Junior [MVP | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados | SorBR.Net | Professor Universitário | MSIT.com]

    segunda-feira, 10 de dezembro de 2012 16:39
  • Junior, pensei sobre o assunto, mas será que isso não deixaria a procedure mais lenta, uma vez que o código tem que chamar outro código.

    Mais uma pergunta, se eu dividisse essa procedure em pequenas procedures. Seria possivel que uma procedure criasse tabelas temporarias e as demais utilizassem essas tabelas???

    Abraços, obrigado por me ajudar.

    segunda-feira, 10 de dezembro de 2012 16:58
  • Rafael,

    Teoricamente não é para ficar mais lento, ao contrário você estaria dividindo a carga de trabalho em processamentos paralelos.

    Em relação as tabelas é possível sim criar uma temporária a outras procedures ou sessões utilizarem, mas para isso terá que ser uma table temporária global e não local.

    Vale ressaltar que toda tabela temporária global vai existir enquanto a conexão do usuário na instância do SQL Server estiver em uso e ativa.


    Pedro Antonio Galvão Junior [MVP | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados | SorBR.Net | Professor Universitário | MSIT.com]

    • Marcado como Resposta Rafael R Santos segunda-feira, 10 de dezembro de 2012 18:34
    segunda-feira, 10 de dezembro de 2012 17:54
  • Entendi Junior,

    obrigado

    segunda-feira, 10 de dezembro de 2012 18:34
  • Olá Rafael,

    A primeira coisa que você deve fazer é eliminar o uso de cursores na procedure. 

    Abraço


    MCP – MCTS – MCITP – MCT SQL Server ADM / BI / Dev Sharepoint IBM Optim Certification http://demetriosilva.wordpress.com/

    • Marcado como Resposta Rafael R Santos terça-feira, 11 de dezembro de 2012 16:10
    terça-feira, 11 de dezembro de 2012 14:15
  • Demétrio,

    realemnte você tem razão, eu consegui eliminar um cursor, o C_GERAL, mas o que corre os planos dentro de cada #TEMP_AUX...BD,CV OU ADM não tem como retirar, pois os registros dentro dessas temps variam de acordo com o dia e o plano.

    Já realizei um alteração na procedure, coloquei um loop WHILE no lugar do cursor C_GERAL e troquei alguns selects por set, consegui até agora uma melhoria de aproximadamente 2 minutos e 30 segundos por mês corrido.

    O próximo passo será criar procedures que chamem outras procedures, ou seja irei tentar quebrar essa procedure monstro em procedures menores como o Junior Galvão aconselhou.

    Colocarei os resultados obtidos aqui após a execução.

    Agradeço a todos que opinaram a fim de colaborar com crescimento de conhecimento do forum.

    Abraços, até breve

    terça-feira, 11 de dezembro de 2012 16:18
  • O caminho é este mesmo Rafael,

    Aconsehlho também ddar uma olhada no blog do Fabiano Amorim.

    Abraço


    MCP – MCTS – MCITP – MCT SQL Server ADM / BI / Dev Sharepoint IBM Optim Certification http://demetriosilva.wordpress.com/

    terça-feira, 11 de dezembro de 2012 21:20
  • Caros,

    realizei a mudança, retirei todos os cursores e quebrei a procedure em procedures menores, mas houve um acrescimo de tempo de 3 segundos.

    CREATE PROCEDURE carga_rentabilidade_grupo
    AS
    BEGIN
    --Cria tabela temporária que irá armazenar todos atributos necessários das tabelas
    --STAGE_RENTABILIDADE_RV; STAGE_RENTABILIDADE_RF; STAGE_RENTABILIDADE_CE; STAGE_RENTABILIDADE_IM
    CREATE TABLE ##TEMP_GRUPO_PAPEIS(
    ID INT IDENTITY(1,1),
    SK_DIM_PLANO INT,
    SK_DT_REF_SALDO INT,
    COD_EMP_CT INT, 
    TIPO CHAR(2)) 
    
    CREATE TABLE ##TEMP_AUX_BD(
    SK_DIM_PLANO INT,
    SK_DT_REF_SALDO INT,
    DATA DATE,
    DATA_AUX DATE,
    COD_EMP_CT INT,
    TIPO CHAR(2))
    
    CREATE TABLE ##TEMP_AUX_CV(
    SK_DIM_PLANO INT,
    SK_DT_REF_SALDO INT,
    DATA DATE,
    DATA_AUX DATE,
    COD_EMP_CT INT,
    TIPO CHAR(2))
    
    CREATE TABLE ##TEMP_AUX_ADM(
    SK_DIM_PLANO INT,
    SK_DT_REF_SALDO INT,
    DATA DATE,
    DATA_AUX DATE,
    COD_EMP_CT INT,
    TIPO CHAR(2))
    
    --Popula tabela TEMP_RENDIMENTO
    INSERT INTO ##TEMP_GRUPO_PAPEIS
    SELECT SK_DIM_PLANO,SK_DT_REF_SALDO,NULL,'RV'
    FROM STAGE_RENTABILIDADE_RV	
    
    INSERT INTO ##TEMP_GRUPO_PAPEIS
    SELECT SK_DIM_PLANO,DT_REF_SLD,NULL,'RF'
    FROM STAGE_RENTABILIDADE_RF	
    
    INSERT INTO ##TEMP_GRUPO_PAPEIS
    SELECT CASE 
    				 COD_EMP_CT 
    					 WHEN 1 THEN 3 
    					 WHEN 3 THEN 2 
    			 END,DT_REF_SALDO,COD_EMP_CT,'CE'
    FROM STAGE_RENTABILIDADE_CE	
    
    INSERT INTO ##TEMP_GRUPO_PAPEIS
    SELECT SK_DIM_PLANO,DT_REF_SLD_IM,NULL,'IM'
    FROM STAGE_RENTABILIDADE_IM 
    
    DECLARE 
    --Variaveis gerais 
    	@DATA DATE,
    	@SK_DT_REF_SALDO INT,
    	@MAX_DT_REF INT,
    	@AUX_DT_REF_SALDO INT,
    	@CONT_LINHAS INT,
    	@COMPARA_DATA DATE,	
    	@DATA_REFERENCIA DATE
    
    --Delimita a data de pesquisa
    SELECT 
    	@SK_DT_REF_SALDO = MIN(SK_DT_REF_SALDO),
    	@MAX_DT_REF = MAX(SK_DT_REF_SALDO)
    FROM 
    	##TEMP_GRUPO_PAPEIS TEMP
    	INNER JOIN
    	DIM_TEMPO DT
    	ON TEMP.SK_DT_REF_SALDO = DT.ID_TEMPO 
    WHERE 
    	CONVERT(DATE,DT.DATA) BETWEEN '2012/10/01' AND '2012/10/31'
    		
    --Referência do loop uma vez que este numero representa a primeira data de pápeis em 2009/11/03 que serve como parametro para
    --os papeis do mês 11 do ano de 2009
    SET @AUX_DT_REF_SALDO = 7247
    
    --Este loop é responsável por percorrer a ##TEMP_GRUPO_PAPEIS que possui todos os papeis dos planos
    WHILE @SK_DT_REF_SALDO <= @MAX_DT_REF --LOOP PRINCIPAL
    	BEGIN
    		IF @AUX_DT_REF_SALDO != @SK_DT_REF_SALDO
    			BEGIN
    				SELECT @DATA = CONVERT(DATE,DATA) FROM DIM_TEMPO WHERE ID_TEMPO = @SK_DT_REF_SALDO
    				SELECT @DATA_REFERENCIA = DBO.DATA_REFERENCIA(@DATA)
    				
    --Insere os papeis nas respectivas tabelas temporarias de seus planos		
    				INSERT INTO ##TEMP_AUX_BD 
    				SELECT SK_DIM_PLANO,SK_DT_REF_SALDO,@DATA,@DATA_REFERENCIA,COD_EMP_CT,TIPO
    				FROM ##TEMP_GRUPO_PAPEIS
    				WHERE SK_DT_REF_SALDO = @SK_DT_REF_SALDO
    				AND SK_DIM_PLANO = 3
    				GROUP BY
    				SK_DT_REF_SALDO,
    				SK_DIM_PLANO,
    				COD_EMP_CT,
    				TIPO
    				ORDER BY TIPO
    																						
    				INSERT INTO ##TEMP_AUX_CV
    				SELECT SK_DIM_PLANO,SK_DT_REF_SALDO,@DATA,@DATA_REFERENCIA,COD_EMP_CT,TIPO
    				FROM ##TEMP_GRUPO_PAPEIS
    				WHERE SK_DT_REF_SALDO = @SK_DT_REF_SALDO
    				AND SK_DIM_PLANO = 2
    				GROUP BY
    				SK_DT_REF_SALDO,
    				SK_DIM_PLANO,
    				COD_EMP_CT,
    				TIPO
    				ORDER BY TIPO
    				
    				INSERT INTO ##TEMP_AUX_ADM
    				SELECT SK_DIM_PLANO,SK_DT_REF_SALDO,@DATA,@DATA_REFERENCIA,COD_EMP_CT,TIPO
    				FROM ##TEMP_GRUPO_PAPEIS
    				WHERE SK_DT_REF_SALDO = @SK_DT_REF_SALDO
    				AND SK_DIM_PLANO = 1
    				GROUP BY
    				SK_DT_REF_SALDO,
    				SK_DIM_PLANO,
    				COD_EMP_CT,
    				TIPO
    				ORDER BY TIPO
    --Verifica se existem linhas para ##TEMP_AUX_BD
    				SELECT @CONT_LINHAS = COUNT(*) FROM ##TEMP_AUX_BD
    					IF @CONT_LINHAS != 0
    						BEGIN
    							EXEC DBO.BD_RENTABILIDADE_GRUPO	@SK_DT_REF_SALDO, @DATA, @DATA_REFERENCIA;
    						END 
    				SELECT @CONT_LINHAS = COUNT(*) FROM ##TEMP_AUX_CV
    					IF @CONT_LINHAS != 0
    						BEGIN
    							EXEC DBO.CV_RENTABILIDADE_GRUPO	@SK_DT_REF_SALDO, @DATA, @DATA_REFERENCIA;
    						END
    				SELECT @CONT_LINHAS = COUNT(*) FROM ##TEMP_AUX_ADM
    					IF @CONT_LINHAS != 0
    						BEGIN
    							EXEC DBO.ADM_RENTABILIDADE_GRUPO	@SK_DT_REF_SALDO, @DATA, @DATA_REFERENCIA;
    						END
    				SELECT @AUX_DT_REF_SALDO = @SK_DT_REF_SALDO
    				TRUNCATE TABLE ##TEMP_AUX_BD
    				TRUNCATE TABLE ##TEMP_AUX_CV
    				TRUNCATE TABLE ##TEMP_AUX_ADM
    			END -- Fim do IF @AUX_DT_REF_SALDO != @SK_DT_REF_SALDO
    		SELECT @DATA = CONVERT(DATE,DATA) FROM DIM_TEMPO WHERE ID_TEMPO = @SK_DT_REF_SALDO
    		SELECT @DATA = DBO.DATA_SEGUINTE(@DATA) 			
    		SELECT @SK_DT_REF_SALDO = ID_TEMPO FROM DIM_TEMPO WHERE CONVERT(DATE,DATA) = @DATA							
    	END
    END
    -------------------------------------------------------
    ----------Procedure DBO.BD_RENTABILIDADE_GRUPO---------
    -------------------------------------------------------
    CREATE PROCEDURE bd_rentabilidade_grupo
    	@SK_DT_REF_SALDO INT, 
    	@DATA DATE,
    	@DATA_REFERENCIA DATE,
    AS
    BEGIN
    DECLARE
    	@COMPARA_DATA DATE,
    	@QNT_LINHAS INT,
    	@TIPO_GERAL CHAR(2),
    	--PAPEIS_CE
    	@DT_REF_COTA_CE DATE,
    	@VL_AMORTIZACAO_CE MONEY,
    	@VL_SALDO_ATUAL_CE MONEY,
    	@VL_CONCESSAO_CE MONEY,
    --PAPEIS_IM
    	@VL_OPER_COTA_IM MONEY,
    	@PATRIMONIO_IM MONEY,    
    --PAPEIS_RF
    	@VL_OPER_COTA_RF MONEY,
    	@PATRIMONIO_RF MONEY,   
    --PAPEIS_RV
    	@VL_OPER_COTA_RV MONEY,
    	@VL_DIVID_PREV_RV MONEY,
    	@PATRIMONIO_RV MONEY,  
    --Totalizador plano DB
    	@VL_OPER_COTA_TOTAL MONEY,
    	@VL_DIVID_PREV_TOTAL MONEY,
    	@PATRIMONIO_TOTAL MONEY,  
    	@QTD_COTA_TOTAL MONEY,  
    	@VL_COTA_TOTAL MONEY,
    	@AUX_QNT_COTA_ANTERIOR_TOTAL MONEY,
    	@RENTABILIDADE_MES MONEY
    --Inicializa as variáveis
    SELECT 
    	@VL_AMORTIZACAO_CE = 0,
    	@VL_SALDO_ATUAL_CE = 0,
    	@VL_CONCESSAO_CE = 0,
    	@VL_OPER_COTA_IM = 0,
    	@PATRIMONIO_IM = 0,   
    	@VL_OPER_COTA_RF = 0,
    	@PATRIMONIO_RF = 0,   
    	@VL_OPER_COTA_RV = 0,
    	@VL_DIVID_PREV_RV = 0,
    	@PATRIMONIO_RV = 0,
    	@VL_OPER_COTA_TOTAL = 0,
    	@VL_DIVID_PREV_TOTAL = 0,
    	@PATRIMONIO_TOTAL = 0,  
    	@QTD_COTA_TOTAL = 0,  
    	@VL_COTA_TOTAL = 0,
    	@AUX_QNT_COTA_ANTERIOR_TOTAL = 0,
    	@RENTABILIDADE_MES = 0
    --@COMPARA_DATA é a referência da data @DATA do papel
    	SELECT @COMPARA_DATA = @DATA_REFERENCIA
    		
    		WHILE @COMPARA_DATA <= @DATA
    			BEGIN
    				SELECT @QNT_LINHAS = COUNT(SK_DIM_PLANO) FROM ##TEMP_AUX_BD 
    				WHILE @QNT_LINHAS >= 1	--Loop da ##TEMP_AUX_BD
    					BEGIN
    						SELECT @TIPO_GERAL = X.TIPO 
    						FROM (SELECT ROW_NUMBER() OVER(ORDER BY TIPO) AS LINHA,TIPO FROM ##TEMP_AUX_BD) AS X
    						WHERE X.LINHA = @QNT_LINHAS
    --Pápeis do EMPRÉSTIMO												
    						IF @TIPO_GERAL = 'CE'												
    							BEGIN						
    								SELECT 														 
    									@DT_REF_COTA_CE = CONVERT(DATE,SD.DT_REF), 
    									@VL_AMORTIZACAO_CE = SUM(VL_AMORTIZACAO), 
    									@VL_SALDO_ATUAL_CE = SUM(VL_SALDO_ATUAL)
    								FROM DBINTECH.DBO.CE_SALDO_DIARIO_CONTRATO SD, DBINTECH.DBO.CE_CONTRATOS CE
    								WHERE 
    									SD.CD_FUNDACAO  = '01'
    									AND CONVERT(DATE,SD.DT_REF) = @COMPARA_DATA
    									AND SD.SEQ_PREST   = (SELECT MAX(SD1.SEQ_PREST)
    																				FROM DBINTECH.DBO.CE_SALDO_DIARIO_CONTRATO SD1
    																				WHERE SD1.CD_FUNDACAO  = SD.CD_FUNDACAO
    																					AND SD1.ANO_CONTRATO = SD.ANO_CONTRATO
    																					AND SD1.NUM_CONTRATO = SD.NUM_CONTRATO
    																					AND SD1.DT_REF       = SD.DT_REF)
    									AND CE.CD_FUNDACAO  = SD.CD_FUNDACAO
    									AND CE.ANO_CONTRATO = SD.ANO_CONTRATO
    									AND CE.NUM_CONTRATO = SD.NUM_CONTRATO
    									AND CE.CD_FUNDACAO  = SD.CD_FUNDACAO
    									AND CE.ANO_CONTRATO = SD.ANO_CONTRATO
    									AND CE.NUM_CONTRATO = SD.NUM_CONTRATO
    									AND ((CE.CD_SITUACAO = 3 AND CE.DT_CREDITO <= SD.DT_REF)
    									 OR  (CE.CD_SITUACAO = 5 AND CE.DT_QUITACAO >= SD.DT_REF AND CE.DT_CREDITO <= SD.DT_REF)
    									 OR  (CE.CD_SITUACAO = 5 AND CE.DT_QUITACAO < SD.DT_REF
    												AND (SELECT COUNT(*)
    														 FROM DBINTECH.DBO.CE_PRESTACOES CP
    														 WHERE CP.CD_FUNDACAO  = CE.CD_FUNDACAO
    															 AND CP.ANO_CONTRATO = CE.ANO_CONTRATO
    															 AND CP.NUM_CONTRATO = CE.NUM_CONTRATO
    															 AND CP.SEQ_PREST < 1000
    															 AND (CP.DT_PAGTO IS NULL OR (CP.DT_PAGTO > SD.DT_REF AND CP.DT_VENC < SD.DT_REF))
    															 AND CP.TIPO IN ('P', 'I')
    															 AND CP.CD_ORIGEM_REC < 51) 
    															 > 0)
    															 )
    									AND SD.CD_EMPRESA = '0002'
    									AND SD.CD_PLANO = 1 --PLANO BD
    								GROUP BY SD.DT_REF, SD.CD_EMPRESA, SD.CD_PLANO
    								ORDER BY SD.DT_REF, SD.CD_EMPRESA, SD.CD_PLANO	
    								
    								SELECT @VL_CONCESSAO_CE = SUM(MD.VL_CONCESSAO) 
    								FROM DBIntech.dbo.CE_MOVIMEN_DIARIA_CONTRATO MD, DBIntech.dbo.CE_CONTRATOS CE
    								WHERE MD.CD_FUNDACAO   = '01'
    									AND MD.DT_REF = @DT_REF_COTA_CE
    									AND MD.CD_EMPRESA    = '0002'
    									AND MD.CD_PLANO      = 1 --PLANO BD
    									AND CE.CD_FUNDACAO  = MD.CD_FUNDACAO
    									AND CE.ANO_CONTRATO = MD.ANO_CONTRATO
    									AND CE.NUM_CONTRATO = MD.NUM_CONTRATO
    								GROUP BY MD.DT_REF, MD.CD_EMPRESA, MD.CD_PLANO
    								ORDER BY MD.DT_REF, MD.CD_EMPRESA, MD.CD_PLANO																																					
    							END --Fim do IF @TIPO_GERAL = 'CE'
    --Pápeis de IMOVÉIS													
    						IF @TIPO_GERAL = 'IM'
    							BEGIN								
    								SELECT 
    									@VL_OPER_COTA_IM = COTA.VL_REC_DESP_COTA, 
    									@PATRIMONIO_IM = COTA.VL_PL_COTA													
    								FROM DBINTECH.DBO.IM_RENTAB_COTA COTA
    									 INNER JOIN DIM_PLANO DP 
    									 ON DP.CART = COTA.CART
    								WHERE CONVERT(DATE,COTA.DT_REF_COTA) = @COMPARA_DATA
    									AND DP.SK_DIM_PLANO = 3--PLANO BD
    									AND COTA.ADM = 9999999
    								ORDER BY 1														
    							END --Fim do IF @TIPO_GERAL = 'IM'
    --Pápeis de RENDA FIXA													
    						IF @TIPO_GERAL = 'RF' --Papaeis do RF
    							BEGIN								
    								SELECT  								
    									@VL_OPER_COTA_RF = COTA.VL_OPER_COTA, 
    									@PATRIMONIO_RF = COTA.VL_PL_COTA
    								FROM DBINTECH.DBO.RF_RENTAB_COTA COTA
    									INNER JOIN
    									DIM_PLANO DP
    									ON DP.CART = COTA.CART
    								WHERE CONVERT(DATE,DT_REF_COTA) = @COMPARA_DATA
    									AND PAPEL_RF ='ZZZZZ'
    									AND DP.SK_DIM_PLANO = 3--PLANO BD
    									AND ADM = 9999999
    									AND ANO_PAP = 0
    									AND SEQ_PAP = 0
    								ORDER BY 
    									DT_REF_COTA
    							END --Fim do IF @TIPO_GERAL = 'RF'
    --Pápeis de RENDA VARIÁVEL													
    						IF @TIPO_GERAL = 'RV'
    							BEGIN								
    								SELECT 									
    									@VL_OPER_COTA_RV = COTA.VL_OPER_COTA,
    									@VL_DIVID_PREV_RV = COTA.VL_DIVID_PREV,
    									@PATRIMONIO_RV = COTA.VL_MERC_COTA
    								FROM DBIntech.dbo.RV_RENTAB_COTA COTA
    									INNER JOIN DIM_PLANO DP 
    									ON DP.CART = COTA.CART_COTA						
    								WHERE CONVERT(DATE,COTA.DT_REF_COTA) = @COMPARA_DATA
    									AND DP.SK_DIM_PLANO = 3--PLANO BD
    									AND COTA.TIPO_COTA = 'ZZZZZ'
    									AND COTA.PAPEL_COTA = 'ZZZZZZZZZZ'
    									AND COTA.ADM_COTA = 999999999
    								ORDER BY 1													
    							END --Fim do IF @TIPO_GERAL = 'RV'
    						
    						SELECT @VL_OPER_COTA_TOTAL = @VL_OPER_COTA_TOTAL + @VL_OPER_COTA_RV + @VL_OPER_COTA_RF + @VL_OPER_COTA_IM + @VL_CONCESSAO_CE
    						SELECT @VL_DIVID_PREV_TOTAL = @VL_DIVID_PREV_TOTAL + @VL_DIVID_PREV_RV 
    						SELECT @PATRIMONIO_TOTAL = @PATRIMONIO_TOTAL + @PATRIMONIO_RV + @PATRIMONIO_IM + @PATRIMONIO_RF + @VL_SALDO_ATUAL_CE
    					  SELECT @VL_AMORTIZACAO_CE = 0, @VL_SALDO_ATUAL_CE = 0, @VL_CONCESSAO_CE = 0, @VL_OPER_COTA_IM = 0, @PATRIMONIO_IM = 0, 
    					  @VL_OPER_COTA_RF = 0, @PATRIMONIO_RF = 0, @VL_OPER_COTA_RV = 0, @VL_DIVID_PREV_RV = 0, @PATRIMONIO_RV = 0
    						SET @QNT_LINHAS = @QNT_LINHAS - 1
    					END --Fim do loop da ##TEMP_AUX_BD				
    --Primeiro calculo da rentabilidade
    				IF @COMPARA_DATA = @DATA_REFERENCIA	
    					BEGIN
    						SELECT @VL_COTA_TOTAL = 100
    						SELECT @QTD_COTA_TOTAL = @PATRIMONIO_TOTAL / @VL_COTA_TOTAL
    						SELECT @AUX_QNT_COTA_ANTERIOR_TOTAL = @QTD_COTA_TOTAL
    					END
    --Cálculos seguintes da rentabilidade											
    				ELSE
    					BEGIN
    						SELECT @VL_COTA_TOTAL = ((@PATRIMONIO_TOTAL - @VL_OPER_COTA_TOTAL) + @VL_DIVID_PREV_TOTAL) / @AUX_QNT_COTA_ANTERIOR_TOTAL
    						SELECT @QTD_COTA_TOTAL = @PATRIMONIO_TOTAL / @VL_COTA_TOTAL
    						SELECT @AUX_QNT_COTA_ANTERIOR_TOTAL = @QTD_COTA_TOTAL
    					END
    --Zera as variáveis que realizam o cálculo
    				SET @VL_OPER_COTA_TOTAL = 0
    				SET @VL_DIVID_PREV_TOTAL = 0
    				SET @PATRIMONIO_TOTAL = 0
    				
    				SELECT @COMPARA_DATA = DBO.DATA_SEGUINTE(@COMPARA_DATA) 										
    			END --Fim do loop do @COMPARA_DATA <= @DATA
    	SET @RENTABILIDADE_MES = ((@VL_COTA_TOTAL/100) - 1) * 100
    	INSERT INTO FATO_RENTABILIDADE_GRUPO VALUES(3,@SK_DT_REF_SALDO,@RENTABILIDADE_MES,NULL)
    END

    terça-feira, 11 de dezembro de 2012 21:27
  • Olá Rafael,

    Seria muito mais performático se você tentasse eliminar os laços e trabalhar de forma "Set Based".

    Abraço


    MCP – MCTS – MCITP – MCT SQL Server ADM / BI / Dev Sharepoint IBM Optim Certification http://demetriosilva.wordpress.com/

    terça-feira, 11 de dezembro de 2012 21:34
  • Caro Demétrio, o laço que realiza os cálculos não se aplica ao pensamento "Set Based".

    Mas tentarei implementar o mesmo pensamento na primeira estrutura.

    quarta-feira, 12 de dezembro de 2012 15:33