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

Optimizar consulta

Estas en el tema de Optimizar consulta en el foro de Mysql en Foros del Web. Hola, tengo la siguiente consulta: select a.id as idp, a.es as nombre,a.foto,b.es as descrip,c.es as precio,c.promo from productos as a, descripcion as b,precio as c ...
  #1 (permalink)  
Antiguo 20/02/2007, 23:45
 
Fecha de Ingreso: enero-2005
Mensajes: 65
Antigüedad: 19 años, 3 meses
Puntos: 0
Optimizar consulta

Hola, tengo la siguiente consulta:
select a.id as idp, a.es as nombre,a.foto,b.es as descrip,c.es as precio,c.promo from productos as a, descripcion as b,precio as c where a.idCategoria=50 and b.idProducto=a.id and c.idProducto=a.id GROUP BY a.id ORDER BY a.id DESC

Weno, respecto a esta consulta comentar que idProducto e id es PK en las tablas que se usa (por lo tanto tiene indice), a parte tengo un indice en idCategoria. Osea todo lo que se usa en el where tiene un indice asociado.

Cuando hago un explain de la consulta obtengo lo siguiente:
table type possible_keys key key_len ref rows Extra
a ref PRIMARY,idCategoria idCategoria 4 const 37 where used; Using temporary
b eq_ref PRIMARY PRIMARY 4 a.id 1
c eq_ref PRIMARY PRIMARY 4 a.id 1

Como veis en la primera linea, en extra tengo where used; Using temporary. Si quito el group by obtengo un using filesort. Como puedo optimizar la consulta para evitar que me hago un filesort o una tabla temporal?

Muchas gracias, un saludo ;)
  #2 (permalink)  
Antiguo 21/02/2007, 00:50
 
Fecha de Ingreso: diciembre-2001
Ubicación: Morelia, México.
Mensajes: 312
Antigüedad: 22 años, 4 meses
Puntos: 0
Re: Optimizar consulta

SELECT
a.id as idp, a.es as nombre, a.foto,
b.es as descrip,
c.es as precio, c.promo
FROM
productos as a
LEFT JOIN
descripcion as b ON b.idProducto = a.id
LEFT JOIN
precio as c ON c.idProducto = a.id
WHERE
a.idCategoria=50
ORDER BY a.id DESC

El GROUP BY no es necesario, según veo.

No entendí muy bien tu pregunta, pero yo haría la consulta así como te la describí, lo bueno es que los datos de las tablas b y c se anexan a los resultados de la tabla a, y eso evita duplicidad de datos en tu tabla resultado, y por tanto se omite el GROUP BY. Claro, si no hay valor que anexar de b y c en la tabla a entonces te generará un campo NULL para que lo tengás en cuenta y no te de errores.

Chao.
  #3 (permalink)  
Antiguo 21/02/2007, 07:45
Avatar de deadlykyo  
Fecha de Ingreso: noviembre-2005
Ubicación: Cbba - Bolivia
Mensajes: 747
Antigüedad: 18 años, 5 meses
Puntos: 5
Re: Optimizar consulta

Holas pitu, estos temas ya han sido tratados, es bueno revisar las reglas del foro y buscar antes tal vez encuentres la respuesta que buscas en otro post, si no es asi puedes postearlo, saludos, cya
http://www.forosdelweb.com/f86/consulta-optimizar-tiempo-respuesta-466285/
__________________
"El Conocimiento es de todos, no solo de algunos"
  #4 (permalink)  
Antiguo 21/02/2007, 11:58
 
Fecha de Ingreso: enero-2005
Mensajes: 65
Antigüedad: 19 años, 3 meses
Puntos: 0
De acuerdo Re: Optimizar consulta

Hola, primero de todo daros las gracias por contestarme. Respecto al ultimo post, ya lo habia mirado antes xo usando joins (como la query que hay en el 2o post de un compañero) la consulta se me ejecuta en 0,0036 y sin usarlos tarda 0,0032 desde localhost. El problema que tengo es que me usa el filesort para odenarlo y segun he leido esto relentiza la ejecucion.

No me queda claro (segun la explicacion que he visto en otro post) como es que el hexo de usar un JOIN deba aumentar la velocidad de ejecucion, ya que un JOIN no es mas que un producto cartesiano con una seleccion (para mi es el mismo concepto que no usar la join aunque por lo que leo no es asi). De hexo ya veis que el tiempo de ejecucion sin usar la join es menor que usandolo. Xq es mas rapido usar un JOIN??

El tema es que me gustaria evitar que use el filesort para que vaya mas rapido. Si quito el order by entonces todo perfecto, xo es cuando lo uso que me provoca el uso del filesort. El group by solo lo habia puesto para evitar el filesort pero por contra me usaba la tabla temporal.

He leido que se puede evitar usando un STRAIGHT_JOIN xo no me queda claro ya que pone que es lo mismo que un INNER JOIN.

Que puedo hacer para que no me use el filesort y por lo tanto mejorar el tiempo de consulta??

Muchisimas gracias ;)

Última edición por Pitu.; 21/02/2007 a las 12:04
  #5 (permalink)  
Antiguo 21/02/2007, 13:08
Avatar de deadlykyo  
Fecha de Ingreso: noviembre-2005
Ubicación: Cbba - Bolivia
Mensajes: 747
Antigüedad: 18 años, 5 meses
Puntos: 5
Re: Optimizar consulta

Holas Pitu, te explico la diferencia entre usar o no JOINS con un ejemplo, cuando haces un select entre dos tablas suponiendo las tablas:
usuario
Código:
idUsuario        Nombre              Login
    1        Miguel Sanchez      miguel.san
    2        Ronal Gomez         rona.gom
    3        Diego Alandia       diego.ala

pagoCuota
idPago     idUsuario         fechaPago            total
   1           1             2006-11-07             50
   2           1             2007-12-09             40
   3           2             2006-12-13             70
   4           2             2007-01-05             90
   5           1             2007-01-15             65
si usas el join en el WHERE, sucede que el motor de MySQL agarra y lee el FROM de tu consulta y como no encuentra JOINS, realiza un producto cartesiano entre las dos tablas en este caso un producto cartesiano nos generaria 15 registros, y recien despues de generarlos empieza con la sentencia WHERE y empieza a discriminar los resultados y quedarian solo 5, pero si usas los JOINS MySQL empieza a discriminar cuales cumplen la condicion del FROM y luego pasa al WHERE quedando 5 registros desde el principio, claro esto no se nota nada en 100, 200 registros, pero cuando trabajes con cantidades como 10000 registros en una, 50000 en otra, y alrededor 200000 en una tabla intermedia de ambas imagina un join entre esas tres tablas, no me puedo dar el lujo de generar 50000*10000*200000 registros, es por eso el uso del JOIN, ahora sobre tu using filesort, no se ve que salga eso y sobre la tabla temporal no deberia salir eso ya que solo sale eso si es que usas GROUP BY y ORDER BY sobre columnas diferentes, me parece raro que te salga eso, porque no pones la estructura de tus tablas tal vez ahi tengamos algun indicio de que puede ser, saludos, cya
__________________
"El Conocimiento es de todos, no solo de algunos"
  #6 (permalink)  
Antiguo 21/02/2007, 17:53
 
Fecha de Ingreso: enero-2005
Mensajes: 65
Antigüedad: 19 años, 3 meses
Puntos: 0
Re: Optimizar consulta

Muchisimas gracias por responder, ahora si que me ha quedado clarisimo. Ahora parto de la sentencia escrita por el compañero en el post 2. La salida exacta que me da el explain es la siguiente:
table type possible_keys key key_len ref rows Extra
a ref idCategoria idCategoria 4 const 37 where used; using filesort
b eq_ref PRIMARY PRIMARY 4 a.id 1
c eq_ref PRIMARY PRIMARY 4 a.id 1

Las tablas en cuestion son:
producto:
id int(11) auto_increment -->PK
idSubcategoria int(11) --> indice
es varchar(75)
en varchar(75)
fr varchar(75)
al varchar(75)
foto varchar(100)
novedad int(1)
idCategoria int(11) --> indice
ref varchar(25)
compra int(11)

precio:
idProducto int(11) --> PK
es decimal(7,2)
en decimal(7,2)
fr decimal(7,2)
al decimal(7,2)
promo int(1)

descripcion:
idProducto int(11) --> PK
es varchar(255)
en varchar(255)
fr varchar(255)
al varchar(255)

A ver si vemos que puede pasar ;) muchas gracias por todo!!
  #7 (permalink)  
Antiguo 21/02/2007, 20:42
Avatar de deadlykyo  
Fecha de Ingreso: noviembre-2005
Ubicación: Cbba - Bolivia
Mensajes: 747
Antigüedad: 18 años, 5 meses
Puntos: 5
Re: Optimizar consulta

Puede que creando un indice a los campos id y idCategoria se arregle el problema
Código PHP:
mysql>CREATE INDEX id_idCategoria ON producto (ididCategoria); 
me olvide decirte una cosa mas, si puedes poner info sobre los indices que tiene cada tabla:
Código PHP:
mysql>SHOW INDEX FROM producto;
mysql>SHOW INDEX FROM descripcion;
mysql>SHOW INDEX FROM precio
saludos, cya
__________________
"El Conocimiento es de todos, no solo de algunos"
  #8 (permalink)  
Antiguo 22/02/2007, 14:00
 
Fecha de Ingreso: enero-2005
Mensajes: 65
Antigüedad: 19 años, 3 meses
Puntos: 0
Re: Optimizar consulta

Muchas gracias deadlykyo. Si creo el indice que me indicas me dice que el campo que es PK (en este caso, id) no puede estar en dos indices diferentes. Si borro los indices que tengo y pongo solo el compuesto, volvemos un paso atras ya que escanea las 299 tuplas.

Te pongo el resultado de los shows:
mysql>SHOW INDEX FROM producto;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
producto 0 PRIMARY 1 id A 299 NULL NULL
producto 1 idCategoria 1 idCategoria A 15 NULL NULL
producto 1 idSubcategoria 1 idSubcategoria A 21 NULL NULL


mysql>SHOW INDEX FROM descripcion;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
descripcion 0 PRIMARY 1 idProducto A 299 NULL NULL


mysql>SHOW INDEX FROM precio;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
precio 0 PRIMARY 1 idProducto A 299 NULL NULL

Si quito el ORDER BY ya no me sale el using filesort, xo sq necesito obtener el resultado ordenado... siempre que lo uso me hace lo del filesort, en esta otra sentencia tb me lo hace:
explain select es,id,link from categorias order by es ASC :(

Te agradezco muchisimo que me dediques parte de tu tiempo, a ver si conseguimos arreglar esto ;)

P.D: ahora estoy mirandome los tipos de JOIN que hay y he visto que el LEFT JOIN devuelve los mismos resultados que un JOIN y ademas, retorna las tuplas de la tabla de la izquierda que no tienen nada asociado en la tabla de la derecha (NULL). Según esto, como es que en la sentencia que puso CBBzun en el post 2, usa LEFT JOIN y no JOIN?? por algun motivo en especial o un JOIN seria más optimo? de todas maneras en mi mysql 4 me da error cuando hago una sentencia usando JOIN y ON: select campo from tabla1 JOIN tabla2 ON (tabla1.campo = tabla2.campo2) WHERE xxx merciiiiiiiii ;)

Última edición por Pitu.; 22/02/2007 a las 17:59
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 21:30.