entre Desarrolladores

Recibe ayuda de expertos

Registrate y pregunta

Es gratis y fácil

Recibe respuestas

Respuestas, votos y comentarios

Vota y selecciona respuestas

Recibe puntos, vota y da la solución

Pregunta

2votos

Ayuda a evaluar si mi consulta SQL es la más optima

Hola , a mi Parecer esta sería La forma optima de Hacer la actualización pero aun soy muy novato en el tema, me gustaria saber de otros puntos de vista y como se podría optimizar la consulta expuesta en caso de haber una mejor implementación.

UPDATE ColocRecupCarteraVenc 
SET nCapRecuperado= calc.nCapRecuperado from  ColocRecupCarteraVenc CV JOIN(SELECT SUM(mcd.nMonto) as nCapRecuperado,mcd.cCtacod
                            FROM mov m
                                INNER JOIN movcol mc on mc.nMovNro=m.nMovNro
                                INNER JOIN movcoldet mcd on mcd.nMovNro=mc.nMovNro and mcd.cOpeCod=mc.cOpeCod and mcd.cCtaCod=mc.cCtaCod
                                INNER JOIN ColocRecupCarteraVenc V ON V.cCtaCod = MC.cCtaCod
                            WHERE m.nMovFlag=0
                                AND mc.cOpeCod like '100[234567]%'
                                AND mcd.nPrdConceptoCod IN (1000,1010)
                                --AND MC.cCtaCod = CV.cCtaCod
                                AND DBO.FechaHoraMovDate(M.cMovNro)>DBO.FechaHoraMovDate(V.cMovNroActualizacion)
                                AND V.cPeriodo=(select max(cperiodo) from  ColocRecupCarteraVenc)
                            GROUP BY mcd.cCtacod)as calc ON calc.cCtaCod = CV.cCtaCod

0voto

Leonardo-Tadei comentado

Nos podrías pasar las estructuras de las tablas implicadas, sus índices y una breve explicación de cuál es la semántica de transacción?

Con lo de "semántica de la transacción" quiero preguntarte la idea detrás de la operación, como por ejemplo "actualizar el saldo de la cuenta corriente del cliente".

Con esto podremos analiar la query y además la normalización del almacenamiento...

0voto

Jaox comentado

La semántica de la transacción es básicamente actualizar el saldo de capital recuperado en la tabla auxiliar ColocRecupCarteraVenc, agradezco mucho tu respuesta y lamentablemente no puedo proporcionarte la estcructura completa de las tablas por una cuestión de reservas de la institución, pero te puedo dar la idea conceptual de las tablas para que facilitarte el análisis:

ColocRecupCarteraVenc: almacena los números de cuentas (cCtaCod) y el saldo del capital recuperado entre otros datos.
-movcol: almacena los movimientos de pago a modo de cabecera identificado con nMovNro.
-movcoldet: almacena los detalles del movimiento relacionado con nMovNro de movcol.
Las tres tablas se indexan por cCtaCod

"AND mc.cOpeCod like '100[234567]%'
AND mcd.nPrdConceptoCod IN (1000,1010)" sirve para filtrar que sean estrictamente pagos y sean pagos de capital más no de otro concepto.

FechaHoraMovDate() , transforma una cadena por ejemplo '20141005DFSD..." en una fecha y poder compararlo con las fechas posteriores a los registros de ColocRecupCarteraVenc para solo evaluar los pagos posteriores al ingreso de los registros en esta tabla pues me interesa actualizar solo los posteriores.

Espero te sirva un poquito para que me puedas brindar tu opinión.

1 Respuesta

2votos

Leonardo-Tadei Puntos227320

La estructura de 3 o 4 tablas son reservadas por la institución? Espero que sea una broma y que yo no la entienda... los datos claro que son privados y reservados, pero la estructura?? Hay países incluso en que la estructuras de tablas que almacenen datos personales debe ser declarada... en fin.

Volviendo a tu problema y sin las estructuras, solo puedo recomendarte que crees índices para las campos usados en las relaciones.

movcol.nMovNro
movcoldet.nMovNro
movcoldet.cOpeCod
etc.

De esta forma las relaciones se armarán desde índices que es mucho más rápido.

Por último, estoy 98% seguro de que tenés los almacenamientos mal normalizados, ya que estás manteniendo valores en tablas que se podrían calcular recorriendo los registros de otras, y esto es una repetición.
No hay que guardar lo que se puede calcular

Saludos cordiales!

0voto

Jaox comentado

Gracias por tus recomendaciones; en cuestión de sintaxis, ¿está bien que haga un JOIN(subconsulta) o tal vez los resultados serian más rápidos si los consulto a partir de una tabla temporal?.

otra duda que me acaba de surgir tiene que ver con esta linea:

AND V.cPeriodo=(select max(cperiodo) from  ColocRecupCarteraVenc)

Aquí realizó un filtro para que solo actualice los saldos del periodo actual (cperiodo es un varchar de la forma 201501 : que es año y mes), la duda es la siguiente:

¿Esta bien que escriba la subconsulta para obtener el máximo periodo en el WHERE, o talvez deba declarar una variable @cPeriodo y realizar la subconsulta en primeras quedando asi:

DECLARE  @cPeriodo VARCHAR(6);
SET @cPeriodo= (select max(cperiodo) from  ColocRecupCarteraVenc);
.
.(codigo)
.
WHERE ... AND V.cPeriodo=@cPeriodo....

¿Ayudaría de alguna manera este cambio, o es irrelevante?. gracias de antemano.

Saludos.

0voto

Leonardo-Tadei comentado

Hola @Jaox,

tenés los almacenamientos mal normalizados. Se nota en que estás actualizando un saldo en vez de simplemente agregar un pago al periodo correspondiente.

De ahí en adelante, yo no puedo ayudarte, porque te estaría ayudando a hacer algo que no hay que hacer :-(

Querés eficiencia y optimización en las consultas? Normalizá tus tablas! Los SGDBMS son piezas de software extremadamente óptimas y eficientes para trabajar con datos en al menos 3ra Forma Normal.

Con almacenamientos normalizados, es probable que jamás tengas que escribir una subconsulta

0voto

Jaox comentado

En realidad el diseño del modelo se fue "desescalabilizando" a medida que los datos y la lógica de negocio fue sufriendo cambios, yo no he diseñado el modelo relacional del sistema en primera instancia, yo he decidido captar información y aislar esa información para trabajar en un modulo en especifico, algo así como alimentar una tabla auxiliar para trabajar más eficientemente sobre datos procesados, preferible para mi a estar procesando esas información cada vez que el modulo lo necesite, si he optado por ello es porque he necesitado hacerlo debido a que hay grandes cantidades de datos de distintos tipos en un aspecto de la base de datos y a mi solo me interesa filtrar un tipo en especifico y la única forma que se me ha ocurrido es hacerlo así, no creo que ahora la entidad quiera hacer una normalización de su modelo y eso también es lamentable para mi.
Estoy consciente del mal manejo al almacenar, pero esperaba al menos hacerlo lo más optimo posible para que al menos sea un mal menor y en general me funcione relativamente bien.

De igual manera, comparto tu punto de vista y se agradece la ayuda que pude obtener.

"Aunque trabaje con mala arcilla, espero al menos moldear una vasija sin huecos"

0voto

Leonardo-Tadei comentado

Te entiendo perfectamente @Jaox y nunca fue mi intención hacerte una crítica personal...

Si tu situación es que "la cosa es así" y estás haciendo un nuevo módulo de software, el mejor camino es crear ese módulo como si fuera un sistema desde cero, con sus almacenamientos normalizados, y correr todas las noches un proceso batch que haga las actualizaciones de un lado para el otro.

Siempre podés decir que es más óptimo pasar datos de un software al otro que andar haciendo querys kilométricas para cada transacción... e incluso es posible que no estés mintiendo ;-)

Con el tiempo lo más probable es que veas que tu software irá creciendo, porque está bien concebido, errgo, funcionará más rápido y mejor, y se irá agrandando para ir haciendo la tarea del viejo software, hasta que al final quede reemplazado. Es a veces más fácil ponerse manos a la obra con algo chico y un plan a largo plazo que conseguir el permiso para implementar una migración.

Saludos!

PD: igual, ante un cambio en la empresa sobre un software originalmente bien Normalizado, se debería asumir el costo del cambio para que a fin del proceso haya un software ligeramente diferente e igual de bien normalizado.

Por favor, accede o regístrate para responder a esta pregunta.

Otras Preguntas y Respuestas


...

Bienvenido a entre Desarrolladores, donde puedes realizar preguntas y recibir respuestas de otros miembros de la comunidad.

Conecta