Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General » Mysql »

Subconsulta NOT IN muy lenta

Estas en el tema de Subconsulta NOT IN muy lenta en el foro de Mysql en Foros del Web. buenos días foreros. Vengo con otro problema más, pues tengo un problema con una subconsulta NOT IN. Y no es un problema de programación pues ...
  #1 (permalink)  
Antiguo 04/05/2015, 11:27
Avatar de planmental  
Fecha de Ingreso: abril-2015
Mensajes: 100
Antigüedad: 9 años
Puntos: 0
Subconsulta NOT IN muy lenta

buenos días foreros.

Vengo con otro problema más, pues tengo un problema con una subconsulta NOT IN.

Y no es un problema de programación pues todo sale bien, mi problema es que es muy lento el proceso y es que necesito hacer varios querys con la misma subconsulta en la misma página php.

El código es el siguiente:
Código MySQL:
Ver original
  1. SELECT MAX(fecha) fecha,  id, remolque FROM vehiculos
  2. WHERE cliente ='".$f['cliente']."' AND remolque
  3. NOT IN (SELECT remolque FROM vehiculos WHERE cliente ='".$f['cliente']."'
  4. AND localidad = 'BASE') GROUP BY remolque

Tengo que sacar todos los remolques de la tabla vehiculos pero si el local dice 'BASE' que no me los muestre. Todo sale muy bien justo como lo necesito, pero mi problema radica en que es muy lenta la consulta por la razón de que son varios códigos como los que muestro arriba. Y lo que necesito es si existe otra opción a la subconsulta un poco más rápida.

PD: manejo solo una tabla.

Por su atención gracias.

Última edición por gnzsoloyo; 04/05/2015 a las 11:33
  #2 (permalink)  
Antiguo 04/05/2015, 11:29
Avatar de Libras
Colaborador
 
Fecha de Ingreso: agosto-2006
Ubicación: En la hermosa perla de occidente
Mensajes: 7.412
Antigüedad: 17 años, 8 meses
Puntos: 774
Respuesta: Subconsulta NOT IN muy lenta

Utiliza exists en lugar de In te dara mejores resultados de performance :)
__________________
What does an execution plan say to t-sql query? Go f**k yourself, if you are not happy with me
  #3 (permalink)  
Antiguo 04/05/2015, 11:42
Avatar de planmental  
Fecha de Ingreso: abril-2015
Mensajes: 100
Antigüedad: 9 años
Puntos: 0
Respuesta: Subconsulta NOT IN muy lenta

Hola Libras.

Como comentas quite IN y escribí EXISTS pero me sale el error:

Código:
Warning: mysql_num_rows() expects parameter 1 to be resource, boolean given in C:\xampp\htdocs\inv\clientes.php on line 99
que es donde se encuentra el codigo:

Cita:
Editado: Código de programacion no permitido en foros de BBDD.
Leer las reglas del foro, por favor.
y asi es como quedó el código no sé si haya hecho algo mal:
Cita:
Editado: Código de programacion no permitido en foros de BBDD.
Leer las reglas del foro, por favor.
Código MySQL:
Ver original
  1. SELECT MAX(fecha) fecha,  id, remolque FROM vehiculos
  2. WHERE cliente ='".$f['cliente']."' AND remolque
  3. NOT EXISTS (SELECT remolque FROM vehiculos WHERE cliente ='".$f['cliente']."'
  4. AND localidad = 'BASE') GROUP BY remolque

Última edición por gnzsoloyo; 04/05/2015 a las 12:16
  #4 (permalink)  
Antiguo 04/05/2015, 11:45
Avatar de Libras
Colaborador
 
Fecha de Ingreso: agosto-2006
Ubicación: En la hermosa perla de occidente
Mensajes: 7.412
Antigüedad: 17 años, 8 meses
Puntos: 774
Respuesta: Subconsulta NOT IN muy lenta

Código MySQL:
Ver original
  1. SELECT MAX(fecha) fecha,  id, remolque FROM vehiculos
  2. WHERE cliente ='".$f['cliente']."' AND  
  3. NOT EXISTS (SELECT remolque FROM vehiculos WHERE cliente ='".$f['cliente']."'
  4. AND localidad = 'BASE') GROUP BY remolque
Prueba con algo asi :)
__________________
What does an execution plan say to t-sql query? Go f**k yourself, if you are not happy with me

Última edición por gnzsoloyo; 04/05/2015 a las 12:17
  #5 (permalink)  
Antiguo 04/05/2015, 11:56
Avatar de planmental  
Fecha de Ingreso: abril-2015
Mensajes: 100
Antigüedad: 9 años
Puntos: 0
Respuesta: Subconsulta NOT IN muy lenta

Hola Libras.

Puse el código como me dijiste y no sale error pero me sale cero y me debe de salir 3.

Lo que necesito es que al seleccionar un cliente pueda ver los remolques que tiene dicho cliente pero los números de remolque se repiten por lo tanto estoy seleccionando solo los remolques que tengan la fecha más alta sin repetir remolques.

Ya teniéndolos necesito que sólo me seleccione los remolques que no tenga 'BASE' en la localidad pues quiere decir que ya fue entregado dicho remolque.

Ya he intentado sin subconsulta colocando simplemente not like o != 'BASE' pero me salen los cuatro remolques incluyendo el que dice 'BASE' pues va al siguiente registro de dicho remolque que no dice 'BASE'.

Y con la subconsulta me hace todo bien pues me quita el remolque que tiene la palabra 'BASE' en la localidad pero el problema es que es muy lento.
  #6 (permalink)  
Antiguo 04/05/2015, 12:02
Avatar de Libras
Colaborador
 
Fecha de Ingreso: agosto-2006
Ubicación: En la hermosa perla de occidente
Mensajes: 7.412
Antigüedad: 17 años, 8 meses
Puntos: 774
Respuesta: Subconsulta NOT IN muy lenta

El exists funciona de manera un poco diferente que el In, aqui deberias de leer un poco sobre el exists y ver como acomodar tu consulta, ahora tu tabla tiene indices?? Ahora dices que quieres mostrar los remolques diferentes de un cliente, si es asi porque no simplemente usas distinct???

Código MySQL:
Ver original
  1. SELECT distinct  id, remolque FROM vehiculos
  2. WHERE cliente ='".$f['cliente']."' AND  
  3. AND localidad = 'BASE' GROUP BY remolque
__________________
What does an execution plan say to t-sql query? Go f**k yourself, if you are not happy with me

Última edición por gnzsoloyo; 04/05/2015 a las 12:17
  #7 (permalink)  
Antiguo 04/05/2015, 12:27
Avatar de planmental  
Fecha de Ingreso: abril-2015
Mensajes: 100
Antigüedad: 9 años
Puntos: 0
Respuesta: Subconsulta NOT IN muy lenta

Hola Libras.

Ya lo había intentado con distinct pero me sale 4 (los remolques que tiene el cliente) y tiene que salir 3 por lo mismo por que como hay varios registros con el numero 48 (número del remolque), y la ultima fecha de dicho remolque (que es el que necesito) tiene la palabra 'BASE' en la localidad, entonces si tiene la palabra 'BASE' no debería de contármela y salirme como resultado un 3 contándome los otros 3 remolques nada más.

Pero en vez de ignorar el remolque 48 se pasa al siguiente registro del dicho remolque donde no dice 'BASE' y me sale el 4.

La verdad se supone que por eso estoy poniendo el MAX(fecha) para que sólo me cuente la última fecha de dicho remolque, pero me lo ignora y no sé porqué.

Bueno seguiré intentado pues se me ocurren muchas descabelladas combinaciones pero la mayoría me sale 4

Gracias Libras
  #8 (permalink)  
Antiguo 04/05/2015, 12:29
Avatar de Libras
Colaborador
 
Fecha de Ingreso: agosto-2006
Ubicación: En la hermosa perla de occidente
Mensajes: 7.412
Antigüedad: 17 años, 8 meses
Puntos: 774
Respuesta: Subconsulta NOT IN muy lenta

un ejemplo de tus datos y te podria ayudar un poco mas ;)
__________________
What does an execution plan say to t-sql query? Go f**k yourself, if you are not happy with me
  #9 (permalink)  
Antiguo 04/05/2015, 13:08
Avatar de planmental  
Fecha de Ingreso: abril-2015
Mensajes: 100
Antigüedad: 9 años
Puntos: 0
Respuesta: Subconsulta NOT IN muy lenta

No tengo así los datos copiados y pegados porque la base de datos no la manejo yo, desgraciadamente es ajena y solo puedo ver los datos consultándolos.

Pero la tabla es más o menos así

cliente | remolque | fecha | localidad
------------------------------------------------------------------
pepsi | 48 | 2014-08-01 | BASE
pepsi | 48 | 2014-05-14 | area B
pepsi | 48 | 2014-01-02 | area A
pepsi | 23 | 2014-05-02 | local sur
pepsi | 23 | 2014-08-09 | local sur
pepsi | 11 | 2014-09-15 | area A
pepsi | 04 | 2014-01-21 | area A

Bueno no son los datos tal cual pues los tuve que hacer a mano pero es un ejemplo de lo que quiero.

Lo explico:
son cuatro remolques del cliente pepsi 48, 23, 11, 04 entonces quiero que de esos remolques me tome los que no digan 'BASE' en su ultimo registro o más bien en su última fecha de registro.

En la ultima fecha del remolque 48 es 2014-08-01 pero dice 'BASE' por lo tanto ya fue entregada y por eso no debería de contarmelo en la consulta y descartar el remolque.

Pero en vez de eso lo que hace es pasarse al siguiente registro del remolque 48 con la fecha 2014-05-14 que dice area B y por lo tanto me sigue contando dicho remolque y lo que no quiero es que se brinque al siguiente registro.

Gracias por tu atención y si no me explico dímelo para ver si puedo aclarar mejor
  #10 (permalink)  
Antiguo 04/05/2015, 13:22
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 5 meses
Puntos: 2658
Respuesta: Subconsulta NOT IN muy lenta

Código MySQL:
Ver original
  1. FROM (SELECT cliente, remolque, fecha, localidad
  2.   FROM
  3.     (SELECT cliente, remolque, fecha, localidad
  4.     FROM vehiculos
  5.     WHERE cliente ='".$f['cliente']."'
  6.     ORDER BY fecha DESC) T1
  7.   GROUP BY cliente, remolque) T2
  8. WHERE localidad !='BASE'
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #11 (permalink)  
Antiguo 04/05/2015, 13:43
Avatar de planmental  
Fecha de Ingreso: abril-2015
Mensajes: 100
Antigüedad: 9 años
Puntos: 0
Respuesta: Subconsulta NOT IN muy lenta

Muchas gracias gnzsoloyo!!!!

En efecto se optimizó la consulta

Aunque se ve más complejo jaja pero vaya que la mejoró.

Muchas gracias a los dos por su atención se los agradezco.

Un saludo y muchas gracias de nuevo
  #12 (permalink)  
Antiguo 04/05/2015, 13:49
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 5 meses
Puntos: 2658
Respuesta: Subconsulta NOT IN muy lenta

El problema es que tu query requiere tres niveles de condicioens que son mutuamente incompatibles.
Por eso hay quye hacerlo en forma escalonada, desde la mas general a la más especifica.
1) Cliente
2) Orden
3) Localidad.

En realidad esta sintaxis es sólo para MySQL, no funciona con otros, porque estoy aprovechando una particularidad de MySQL, que admite agrupar por sólo algunos campos del SELECT, o incluso campos no declarados.
En esos casos lo que hace es tomar el primer registro que cumple la condición, descartando el resto. Por eso primero lo ordeno y luego lo agrupo.

¿Se entiende la idea?

Para hacer lo mismo en otros DBMS hay que reescribirla.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #13 (permalink)  
Antiguo 04/05/2015, 13:52
Avatar de Libras
Colaborador
 
Fecha de Ingreso: agosto-2006
Ubicación: En la hermosa perla de occidente
Mensajes: 7.412
Antigüedad: 17 años, 8 meses
Puntos: 774
Respuesta: Subconsulta NOT IN muy lenta

Un poco diferente la consulta a como la podria lograr en SQL server, pero muy buena explicacion gnzsoloyo :)
__________________
What does an execution plan say to t-sql query? Go f**k yourself, if you are not happy with me

Etiquetas: lenta, subconsulta
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 00:39.