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

Consulta SELECT 2 tablas.

Estas en el tema de Consulta SELECT 2 tablas. en el foro de Mysql en Foros del Web. Buenas, queria comentarles una consulta que realizo bien, pero tarda demasiado y puede que no esté optimizada. Tengo dos tablas, una donde guardo traducciones traducciones ...
  #1 (permalink)  
Antiguo 29/08/2010, 06:44
 
Fecha de Ingreso: junio-2009
Mensajes: 309
Antigüedad: 14 años, 10 meses
Puntos: 5
Consulta SELECT 2 tablas.

Buenas, queria comentarles una consulta que realizo bien, pero tarda demasiado y puede que no esté optimizada.

Tengo dos tablas, una donde guardo traducciones

traducciones
- ID_SECCION
- ID_ELEMENTO
- TIPO
- IDIOMA
- TEXTO

y otra llamada widget_videojuegos

widget_videojuegos
- ID
- FECHA
- JUGADO
- VOTOS
- CAT
- IMG


El caso es que en la tabla traducciones guardo el nombre del juego en varios idiomas, bajo el TIPO=1. Ademas en esa misma tabla guardo la información /descripcion del juego bajo el TIPO=2

El ID_SECCION es 4 que es el de este widget, y el ID_ELEMENTO es el de cada juego.


Y aqui dejo la consulta que utilizo

Código PHP:
SELECT 
widget_videojuegos
.ID,
 
traducciones.TEXTO AS NOMBRE
(
SELECT traducciones.TEXTO AS INFO FROM traducciones WHERE traducciones.ID_SECCION=AND traducciones.TIPO=AND traducciones.IDIOMA='1' AND traducciones.ID_ELEMENTO=widget_videojuegos.ID), 
widget_videojuegos.CAT
widget_videojuegos.IMG
widget_videojuegos.JUGADO
widget_videojuegos.FECHA 

FROM widget_videojuegos
traducciones 
WHERE traducciones
.ID_SECCION=AND traducciones.ID_ELEMENTO=widget_videojuegos.ID AND 
traducciones.TIPO=AND traducciones.IDIOMA=

Y si le añado al final un ORDER BY RAND() ya si que se me queda bloqueado el localhost :S


COmo se podria optimizar? Tendria que crear algun indice especial también?

Gracias.
  #2 (permalink)  
Antiguo 29/08/2010, 07:33
Avatar de Vun
Vun
Colaborador
 
Fecha de Ingreso: agosto-2009
Ubicación: Benalmádena, España
Mensajes: 2.265
Antigüedad: 14 años, 8 meses
Puntos: 150
Respuesta: Consulta SELECT 2 tablas.

No entiendo esa subconsulta, ¿NOMBRE e INFO no contienen lo mismo en tu consulta final?
  #3 (permalink)  
Antiguo 29/08/2010, 09:47
 
Fecha de Ingreso: junio-2009
Mensajes: 309
Antigüedad: 14 años, 10 meses
Puntos: 5
Respuesta: Consulta SELECT 2 tablas.

No, por que el campo texto de traducciones, segun el campo TIPO (si es 1 o 2) contiene el nombre o la descripcion del juego. He preparado la tabla asi por que esa tabla me sirve de forma general para la traduccion de cualkier cosa.
  #4 (permalink)  
Antiguo 29/08/2010, 14:07
Avatar de Vun
Vun
Colaborador
 
Fecha de Ingreso: agosto-2009
Ubicación: Benalmádena, España
Mensajes: 2.265
Antigüedad: 14 años, 8 meses
Puntos: 150
Respuesta: Consulta SELECT 2 tablas.

Pues yo veo los dos WHERE iguales, el de la subconsulta y el where final, no se, hay algo que no me encaja xD

WHERE traducciones.ID_SECCION=4 AND traducciones.TIPO=2 AND traducciones.IDIOMA='1' AND traducciones.ID_ELEMENTO=widget_videojuegos.ID

WHERE traducciones.ID_SECCION=4 AND traducciones.TIPO=2 AND traducciones.IDIOMA=1 AND traducciones.ID_ELEMENTO=widget_videojuegos.ID



Otra cosa, ¿el ORDER BY rand() lo quieres para sacar 1 registro al azar, o todos los registros?
  #5 (permalink)  
Antiguo 30/08/2010, 05:00
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: Consulta SELECT 2 tablas.

Hay algunas cosas que debes intentar hacer:
1) Toda relación entre tablas debe establecerse en el FORM y no en el WHERE, porque el WHERE no es optimizable y además cuando llega hasta él, ya ha leido todos los registros, incluyendo los que no sirven.
2) Si una sola de las tablas tiene muchas condiciones de filtrado, es buena práctica crear una subconsulta que restrinja eso.
3) No uses coma o JOIN solamente cuando realices juntas. Eso produce productos cartesianos. Es una de las formas menos eficientes.
4) Usa alias para las tablas. Evitará problemas de escirtura.

Prueba así:
Código MySQL:
Ver original
  1.    WV.ID,
  2.    traducciones.TEXTO NOMBRE,
  3.    T.TEXTO INFO,
  4.    WV.CAT,
  5.    WV.IMG,
  6.    WV.JUGADO,
  7.    WV.FECHA
  8. FROM widget_videojuegos WV INNER JOIN
  9.    (SELECT * FROM traducciones WHERE ID_SECCION = 4 AND TIPO = 2 AND IDIOMA = 1) T
  10.           ON WV.ID  = T.ID_ELEMENTO;

Defectos básicos de lo que hacías:
- Usas una subconsulta en el SELECT para obtener un campo por condiciones que ya tienes en el WHERE. Es redundante y hace que por cada registro de la consulta mayor vuelva a hacer un barrido de toda la tabla TRADUCCIONEs... para obtener lo que ya tiene.
Cita:
No, por que el campo texto de traducciones, segun el campo TIPO (si es 1 o 2) contiene el nombre o la descripcion del juego. He preparado la tabla asi por que esa tabla me sirve de forma general para la traduccion de cualkier cosa.
Eso está mal. No puedes usar un mismo campo para dominios incompatibles. Además, en tu contexto por tu descripcion podemos inferir que el resto de los campos se repite, lo que podría generar inconsistencia de datos, sin contar con la redundancia innecesaria.
Una descripción y un nombre son atributos diferentes de una cosa. No puedes usar un mismo campo para ambas, ni siquiera como lo estás haciendo. Claro, salvo que realmente no te interese aprender sobre diseño de bases de datos...
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #6 (permalink)  
Antiguo 31/08/2010, 15:07
 
Fecha de Ingreso: junio-2009
Mensajes: 309
Antigüedad: 14 años, 10 meses
Puntos: 5
Respuesta: Consulta SELECT 2 tablas.

Muchas gracias por la explicación tan buena.

La verdad es que esta forma de hacer esta tabla la hize asi por que si quiero meter noticias en muchos idiomas, o juegos, o fotos, o videos.... o lo que sea, con esa tabla simple puedo guardar cualquier informacion en cualquier idioma para cualquier cosa de cualquier seccion (NOTICIAS, VIDEOS, FOTOS....)

No tengo ni idea sobre el diseño de base de datos, simplemente me pareció una forma funcional y rapida sin muchas tablas de algo que sirviese de forma infinita para lo que fuese.

Como crees que deberia hacerse?
  #7 (permalink)  
Antiguo 01/09/2010, 07:52
 
Fecha de Ingreso: junio-2009
Mensajes: 309
Antigüedad: 14 años, 10 meses
Puntos: 5
Respuesta: Consulta SELECT 2 tablas.

Cita:
Iniciado por Vun Ver Mensaje
Pues yo veo los dos WHERE iguales, el de la subconsulta y el where final, no se, hay algo que no me encaja xD

WHERE traducciones.ID_SECCION=4 AND traducciones.TIPO=2 AND traducciones.IDIOMA='1' AND traducciones.ID_ELEMENTO=widget_videojuegos.ID

WHERE traducciones.ID_SECCION=4 AND traducciones.TIPO=2 AND traducciones.IDIOMA=1 AND traducciones.ID_ELEMENTO=widget_videojuegos.ID



Otra cosa, ¿el ORDER BY rand() lo quieres para sacar 1 registro al azar, o todos los registros?
Cierto, error mio, deberia ser asi:


WHERE traducciones.ID_SECCION=4 AND traducciones.TIPO=2 AND traducciones.IDIOMA='1' AND traducciones.ID_ELEMENTO=widget_videojuegos.ID

WHERE traducciones.ID_SECCION=4 AND traducciones.TIPO=1 AND traducciones.IDIOMA=1 AND traducciones.ID_ELEMENTO=widget_videojuegos.ID
  #8 (permalink)  
Antiguo 01/09/2010, 08:27
 
Fecha de Ingreso: junio-2009
Mensajes: 309
Antigüedad: 14 años, 10 meses
Puntos: 5
Respuesta: Consulta SELECT 2 tablas.

Creo que debido a mi confusion inicial en el campo TIPO que lo puse en las dos condiciones con 2 he hecho que penseis otra cosa... con lo que os pongo la consulta que he conseguido que funciones, aunque puede que no esté optimizada por que el select dentro del primer select no sabia como meterlo en el form :S

Código MySQL:
Ver original
  1. SELECT wv.ID, tr.TEXTO AS NOMBRE,
  2. (SELECT tr.TEXTO FROM traducciones tr WHERE tr.ID_SECCION=4 AND tr.TIPO=2 AND tr.IDIOMA='1' AND tr.ID_ELEMENTO=wv.ID) AS INFO,
  3. wv.CAT, wv.IMG, wv.JUGADO, wv.FECHA
  4. FROM widget_videojuegos wv LEFT JOIN
  5. traducciones tr ON tr.ID_SECCION=4 AND tr.ID_ELEMENTO=wv.ID AND tr.TIPO=1 AND tr.IDIOMA=1

He intentado meter el LEFT JOIN en una consulta pero a parte que no me coje el campo NOMBRE que creo en esa subconsulta me tarda 8 segundos contra los 0.2 que me tarda la consulta de arriba. Esta es la consulta que uso, aunque seguramente esté mal claro:

Código SQL:
Ver original
  1. SELECT wv.ID,
  2. (SELECT TEXTO FROM traducciones WHERE ID_SECCION=4 AND TIPO=2 AND IDIOMA='1' AND ID_ELEMENTO=wv.ID) AS INFO,
  3. wv.CAT, wv.IMG, wv.JUGADO, wv.FECHA
  4. FROM widget_videojuegos wv LEFT JOIN
  5. (SELECT TEXTO AS NOMBRE, ID_ELEMENTO FROM traducciones WHERE ID_SECCION=4 AND TIPO=1 AND IDIOMA=1) T ON T.ID_ELEMENTO=wv.ID ORDER BY RAND()

Etiquetas: select, tablas
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:52.