locked
optimizar query

    Question

  • alguien sabe una manera mas eficiente de escribir esa query?

    me estan criticando que no es conveniente para procesos batch ,especialmente por el max que tiene ahi dentro , no se de que forma quieren que la escriba.

    SELECT * FROM 
        CONTABILIDAD C1
        INNER JOIN CREDITORECUPERACION CR
    	ON  C1.CodOperacion=CR.CodOperacionActiva 
    	WHERE C1.codoperacion IN
        (
    	     SELECT oac.codoperacionactiva 
    	     FROM  OPERACIONACTIVACALENDARIO  oac
    	     INNER JOIN 
    		(SELECT codoperacionactiva,MAX(NumCuotaCalendario) AS maxcuota 
    		 FROM OPERACIONACTIVACALENDARIO 
    		 GROUP BY codoperacionactiva ) tbl
        ON oac.codoperacionactiva = tbl.codoperacionactiva 
    		  AND oac.NumCuotaCalendario=tbl.maxcuota		
    	WHERE estadocuotacalendario IN ('C','G')
        ) 
        AND  CR.EstadoRecuperacion='H'

    Wednesday, September 26, 2012 3:54 PM

Answers

  • Al parecer, el OP perdió interés por el caso o lo resolvió por él mismo. A pesar de las varias ocasiones en las que se le solicitó información adicional para tratar de optimizar la sentencia, ésta no se recibió, con lo que no se puede progresar en la resolución del tema. No queda alternativa a cerrar el hilo, lo cual es una lástima, dado el tiempo invertido en él. Si este problema persistiera, el OP tendría la opción de reportar la información requerida y continuarlo (o iniciarlo como uno nuevo).

    Alberto López Grande
    SQL Server MVP
    Visita mi blog en http://qwalgrande.com
    Sígueme en twitter en http://twitter.com/qwalgrande

    Saturday, November 10, 2012 10:57 AM
    Moderator

All replies

  • Hola Buen Día, solo me queda una duda con respecto a tu query, este subquery :

    SELECT oac.codoperacionactiva 
    	     FROM  OPERACIONACTIVACALENDARIO  oac
    	     INNER JOIN 
    		(SELECT codoperacionactiva,MAX(NumCuotaCalendario) AS maxcuota 
    		 FROM OPERACIONACTIVACALENDARIO 
    		 GROUP BY codoperacionactiva ) tbl
        ON oac.codoperacionactiva = tbl.codoperacionactiva 
    		  AND oac.NumCuotaCalendario=tbl.maxcuota		
    	WHERE estadocuotacalendario IN ('C','G')

    Te arroja la misma cantidad de registros que este ?? ( segun yo si, pero no sé... ) ya que solo tomaremos el campo codoperacionactiva

    SELECT codoperacionactiva,MAX(NumCuotaCalendario) AS maxcuota 
    FROM OPERACIONACTIVACALENDARIO 
    WHERE estadocuotacalendario IN ('C','G')
    GROUP BY codoperacionactiva 

    Si es así, no podrías hacer el query de la siguiente manera ? 

    SELECT * FROM  -- <<<< AQUI TE SUGIERO PONER SOLO LOS CAMPOS QUE VAYAS A UTILIZAR REALMENTE
        CONTABILIDAD C1
        INNER JOIN CREDITORECUPERACION CR
    	ON  C1.CodOperacion=CR.CodOperacionActiva 
    	 AND  CR.EstadoRecuperacion='H'
    	 INNER JOIN 
        (
    	   
    			SELECT codoperacionactiva,MAX(NumCuotaCalendario) AS maxcuota 
    			FROM OPERACIONACTIVACALENDARIO 
    			WHERE estadocuotacalendario IN ('C','G')
    			GROUP BY codoperacionactiva ) tbl
    	
        ) as aux
        ON aux.codoperacionactiva = C1.codoperacion
       

    Prueba y comentanos como te fue ?


    Sergio Sánchez Arias


    Wednesday, September 26, 2012 4:31 PM
  • lo he optimizado asi

    	UPDATE C1
    	SET C1.Filler='01'
    	FROM CONTABILIDAD C1
        INNER JOIN CREDITORECUPERACION CR  ON  C1.CodOperacion=CR.CodOperacionActiva 
        INNER JOIN OPERACIONACTIVACALENDARIO OAC ON C1.CodOperacion=OAC.CodOperacionActiva  
        INNER JOIN 
    		(SELECT codoperacionactiva,MAX(NumCuotaCalendario) AS MAXCUOTA 
    		 FROM OPERACIONACTIVACALENDARIO 
    		 GROUP BY codoperacionactiva ) TBL	
    	ON OAC.CodOperacionActiva = TBL.CodOperacionActiva 
    	AND OAC.NumCuotaCalendario=TBL.MAXCUOTA
    	AND OAC.EstadoCuotaCalendario ='C' OR OAC.EstadoCuotaCalendario = 'G'
    	AND CR.EstadoRecuperacion='H'

    usando joins me dicn que es mas eficiente que usar subquerys donde puedo ver este rendimiento o alguien puede explicarme porque es .
    Thursday, September 27, 2012 2:27 PM
  • Puedes utilizar el plan de ejecución para verificar eso

    Tutorial básico para interpretar el plan de ejecución de SQL SERVER

    SALUDOS


    Sergio Sánchez Arias

    Thursday, September 27, 2012 7:22 PM
  • gracias , esta simpatico pero para ser honesto no entendi nada

    :(

    no tendras otro mas basico por ahi.

    Thursday, September 27, 2012 10:44 PM
  • Friday, September 28, 2012 1:12 PM
  • gracias por el alcance
    SergioSA(chancrovsky)

    Veo que ningun MVP o las persoans de mayor experiencia responden a mis consultas,que paso?

    los he molestado de alguna manera?

    Friday, September 28, 2012 7:16 PM
  • No molestas a nadie pero supongo que los MVP ayudan voluntareamente, y no estan disponibles 24/365..

    Yo intentaría a cambiar la subconsulta (con la sub-subconsulta) despues del operador In en la siguiente simple subconsulta:

    SELECT	codoperacionactiva,
    		MAX(NumCuotaCalendario) AS maxcuota 
    FROM	OPERACIONACTIVACALENDARIO
    GROUP BY codoperacionactiva
    Having	Sum(Case When estadocuotacalendario IN ('C','G') Then 1 Else 0 End)>0

    no estoy seguro que son logicamente identicas y que te devuelvan el mismo resultado, y no puedo comprobar eso sin datos.

    Admas, hay que verificar que existen indexes aptos!


    El castellano no es mi lengua materna. Discúlpenme por los errores gramaticales, y, si pueden, corríjanme en los comentarios, o por correo electrónico. ¡Muchas gracias! Blog: http://about.me/GeriReshef

    Friday, September 28, 2012 9:04 PM
  • Hola.

    Lo que preguntas no es una cuestión de más o menos experiencia (menos aún por el hecho en sí de ser MVP), sino de que no aportas la información mínima para poder abordar este tipo de cuestiones, esto es, plan de ejecución y lecturas lógicas. En esa línea ya han intentado asesorarte, aportándote formas para que tú mismo puedas empezar a desenvolverte frente a estos casos, aunque veo que sin mucho éxito.

    Tampoco ayuda que primero haya una consulta y luego un update. ¿Cuál es realmente el caso?

    Por favor, aporta esa información y quizá podamos ayudarte, si bien lo ideal sería que tú mismo intentaras revisarlo.


    Alberto López Grande
    SQL Server MVP
    Visita mi blog en http://qwalgrande.com
    Sígueme en twitter en http://twitter.com/qwalgrande

    Thursday, October 18, 2012 7:07 PM
    Moderator
  • el caso es que me objetan el procedure porque dicen que no tiene las mejores practicas de progrmacion y seria lento con los millares de registros qjue tiene que procesar.
    Thursday, October 18, 2012 10:56 PM
  • Hola.

    De acuerdo, no cumple con las normas internas que tengáis en cuanto a programación de sentencias, comprensible, ya que tienes dos subconsultas, una de ellas con una agrupación. Además se estima que será lento, algo que no puedo discutir porque seguimos sin conocer el plan de ejecución ni las lecturas lógicas, ni siquiera si estamos hablando de un update o una select.

    ¿Cómo podemos ayudarte?


    Alberto López Grande
    SQL Server MVP
    Visita mi blog en http://qwalgrande.com
    Sígueme en twitter en http://twitter.com/qwalgrande

    Friday, October 19, 2012 7:10 AM
    Moderator
  • ¿Cómo podemos ayudarte?


    Alberto López Grande
    SQL Server MVP
    Visita mi blog en http://qwalgrande.com
    Sígueme en twitter en http://twitter.com/qwalgrande

    el caso es un update,pongo el select porque supongo que el rendimiento se mide en el select, el problema esque no puedo explicarlo mejor porque ni yo mismo lo entiendo.

    Tienes razon me han pasado enlaces pata medir el costo de las consultas pero no he logrado digerirlas aun

    UPDATE C1
    	SET C1.Filler='01'
    	FROM CONTABILIDAD C1
        INNER JOIN CREDITORECUPERACION CR  ON  C1.CodOperacion=CR.CodOperacionActiva 
        INNER JOIN OPERACIONACTIVACALENDARIO OAC ON C1.CodOperacion=OAC.CodOperacionActiva  
        INNER JOIN 
    		(SELECT codoperacionactiva,MAX(NumCuotaCalendario) AS MAXCUOTA 
    		 FROM OPERACIONACTIVACALENDARIO 
    		 GROUP BY codoperacionactiva ) TBL	
    	ON OAC.CodOperacionActiva = TBL.CodOperacionActiva 
    	AND OAC.NumCuotaCalendario=TBL.MAXCUOTA
    	AND OAC.EstadoCuotaCalendario ='C' OR OAC.EstadoCuotaCalendario = 'G'
    	AND CR.EstadoRecuperacion='H'

    Thursday, October 25, 2012 1:48 PM
  • Hola.

    Aunque en ocasiones el "select" equivalente puede dar una orientación del coste de la sentencia de actualización, no puede tomarse como medida para todos los casos. Un update realiza más cosas que una select.

    Sobre el plan de ejecución y las lecturas lógicas, puedes obtenerlo con Management Studio pulsando Ctrl + M (para que se pinte el plan en modo gráfico) y ejecutando "set statistics io on" (para que se muestren la lecturas y escrituras). Luego lanzar tu update. Saldrán dos pestañas, la de mensajes con las lecturas y el gráfico con el plan de ejecución. Pásanos esa información, a ver si así podemos darte alguna pista.


    Alberto López Grande
    SQL Server MVP
    Visita mi blog en http://qwalgrande.com
    Sígueme en twitter en http://twitter.com/qwalgrande

    Thursday, October 25, 2012 7:02 PM
    Moderator
  • Hola.

    ¿Avanzaste en algo con este tema?


    Alberto López Grande
    SQL Server MVP
    Visita mi blog en http://qwalgrande.com
    Sígueme en twitter en http://twitter.com/qwalgrande

    Sunday, November 04, 2012 8:17 PM
    Moderator
  • Al parecer, el OP perdió interés por el caso o lo resolvió por él mismo. A pesar de las varias ocasiones en las que se le solicitó información adicional para tratar de optimizar la sentencia, ésta no se recibió, con lo que no se puede progresar en la resolución del tema. No queda alternativa a cerrar el hilo, lo cual es una lástima, dado el tiempo invertido en él. Si este problema persistiera, el OP tendría la opción de reportar la información requerida y continuarlo (o iniciarlo como uno nuevo).

    Alberto López Grande
    SQL Server MVP
    Visita mi blog en http://qwalgrande.com
    Sígueme en twitter en http://twitter.com/qwalgrande

    Saturday, November 10, 2012 10:57 AM
    Moderator