MySQL - Otimizar Consulta

 
Vista:

Otimizar Consulta

Publicado por Saul (18 intervenciones) el 09/09/2014 06:03:46
Hola amigo, quisiera ver si me pueden ayudar con mi consulta sql, el problema es este:

Tengo dos tablas
cccxpdetalle = detalle de las transacciones
cccxptransacciones = Cabecera de las transacciones

Lo que necesito es ver si hay cabeceras que no tengan, detalles puesto que en algunas ocaciones, se me pierde el detalle y no tengo cabecera, y estoy haciendo una utileria para rastrear estos hechos.
Ahora bien he tratado de dos formas y pues si bien funcionan, se tornan lentos, y segun veo no son muchos registros
La tabla de detalle tiene 8970 Registros, y la de Cabecera tiene 286.

1
2
3
4
5
6
7
8
9
SELECT numero_cpd As Numero, codprv_cpd As Nit,
			   nomprv_cpd As Proveedor, codcdc_cpd As CCosto
		FROM cccxpdetalle FORCE INDEX (ModEmp)
		WHERE numero_cpd NOT IN (SELECT DISTINCT numero_ccp
		                         FROM cccxptransacciones FORCE INDEX (ModEmp)
		                          WHERE modulo_ccp = '6' AND empresa_ccp = '01')
		AND modulo_cpd = '6'
		AND empresa_cpd = '01'
		GROUP BY modulo_cpd,numero_cpd;

Esto funciona bien pero se me hace que no es la mejor forma, porque en ocaciones ya con los indices como ustedes lo puden ver (FORCE INDEX (ModEmp), esta indixado por Modulo y Empresa, se tarda hasta 30 segundos.

1
2
3
4
5
6
7
8
9
10
11
12
13
SELECT det.numero_cpd As Numero,
       det.codprv_cpd As Nit,
       det.nomprv_cpd As Proveedor,
       det.codcdc_cpd As CCosto,
       cab.grupol_ccp
FROM cccxpdetalle det FORCE INDEX (ModEmp)
    LEFTJOIN cccxptransacciones cab FORCE INDEX (ModEmp) ON
                              cab.numero_ccp = det.numero_cpd
                          AND cab.modulo_ccp  = det.modulo_cpd
                          AND cab.empresa_ccp = det.empresa_cpd
		WHERE det.modulo_cpd = '6'
		AND det.empresa_cpd = '01'
		GROUP BY det.modulo_cpd, det.numero_cpd;

Trate de hacerlo on un LEFT JOIN, pero lo unico que me tira son los registros que coindicen, en este caso son 96, (Cabecera y Detalle AGRUPADOS). y no logro ver como decirle que so lo me muestre los datos que TENGAN Detalle y que les falte la Cabecera.

Por cierto use una comando que se llama EXPLAIN, y pues no me corrigio mucho, o bas bien no se como optimizarlo de la mejor forma.

Estos datos son del primer Query, que es el que me funciona

1- Tabla cccxpdetalle

Type = Ref, possible_key = ModEmp, Key = ModEmp, Key_Len = 13, Ref = Const, Const, Row 2226


2- Tabla cccxptransacciones (SubQuery)

Type = Ref, possible_key = ModEmp, Key = ModEmp, Key_Len = 13, Ref = Const, Const, Row 96

Por favor si alguien me pudiera ayudar quedaria altamente agradecido.

Att.

Saúl
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
Imágen de perfil de xve
Val: 796
Oro
Ha mantenido su posición en MySQL (en relación al último mes)
Gráfica de MySQL

Otimizar Consulta

Publicado por xve (1151 intervenciones) el 09/09/2014 11:30:50
Hola Saul, el NOT IN no es nada aconsejable... si hace un explain, veras que revisas todos los registros varias veces.

La manera correcta es con el LEFT JOIN o RIGHT JOIN, dependiendo de como pongas las tablas

De alguna manera, te tiene que devolver registros NULL...

No utilices group by, ya que si te los agrupa, puede ser que no te los muestre.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Otimizar Consulta

Publicado por Saul (18 intervenciones) el 09/09/2014 19:36:26
Hola xVe, muchicimas gracias, con este detalle me aclaraste un monton de dudas, gracias por tu apoyo.
el código final quedo así y me funciona a la perfección.

Gracias nuevamente Dios te Bendiga compa..

1
2
3
4
5
6
7
8
9
10
11
12
13
14
SELECT det.numero_cpd As Numero,
       det.codprv_cpd As Nit,
       det.nomprv_cpd As Proveedor,
       det.codcdc_cpd As CCosto,
       cab.grupol_ccp
FROM cccxpdetalle det FORCE INDEX (ModEmp)
    LEFT JOIN cccxptransacciones cab FORCE INDEX (ModEmp) ON
                               cab.numero_ccp = det.numero_cpd
                          AND cab.modulo_ccp  = det.modulo_cpd
                          AND cab.empresa_ccp = det.empresa_cpd
		WHERE det.modulo_cpd = '6'
		AND det.empresa_cpd = '01'
    AND grupol_ccp is null                    <----
	GROUP BY det.modulo_cpd, det.numero_cpd
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar
Imágen de perfil de xve
Val: 796
Oro
Ha mantenido su posición en MySQL (en relación al último mes)
Gráfica de MySQL

Otimizar Consulta

Publicado por xve (1151 intervenciones) el 09/09/2014 21:36:37
Gracias por compartirlo Saul!!!
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar