Ver Mensaje Individual
  #2 (permalink)  
Antiguo 05/09/2012, 08:18
leonardo_josue
Colaborador
 
Fecha de Ingreso: enero-2007
Ubicación: México
Mensajes: 2.097
Antigüedad: 17 años, 3 meses
Puntos: 447
Respuesta: Intento optimizar una consulta sql lenta

Hola Illien:

Hay varias cosas que puedes mejorar en tu consulta...

Primero, no listes las tablas en el FROM ni hagas las uniones en el WHERE... en lugar de eso utilizas JOINS, son más eficientes:

Código:
En lugar de esto:

FROM tabla1, tabla2 
WHERE tabla1.campo = Tabla2.campo

Haz esto:

FROM tabla1 
INNER JOIN tabla2 on tabla1.campo = tabla2.campo:
Segundo, hasta donde recuerdo, las comparaciones con REGEXP, tal como las estás poniendo son más lentas que las comparaciones con LIKE '%consulta%'... podrías probar a cambiar estas condiciones... de cualquier manera este tipo de comparaciones SON DE LAS MÁS INEFICIENTES QUE EXISTEN, por lo que deberías tratar de evitarlas a toda costa...

Tercero, verifica que tengas definidos índices en todas tus tablas, tengo un poco de miedo de preguntar, pero al ver esto:

Código:
pelicula.titulo = es_actor_pelicula.tituloPelicula AND
Puedo suponer que estás manejando campos VARCHAR como llaves, sería más sencillo que manejaras índices numéricos como tus campos llaves, en lugar de cadenas...

También tendrías que aclararnos, necesitas realmente incluir todas las tablas en el criterio de búsqueda???, es decir, podrías implementar un tipo de filtro, para que el usuario te definiera sobre qué tabla quiere buscar (titulo, director, idioma, etc.)

Con las recomendaciones anteriores, la consulta podrías probarla más o menos así:

Código MySQL:
Ver original
  1.   pelicula.titulo,
  2.   pelicula.año,
  3.   pelicula.duracion,
  4.   pelicula.pais
  5. FROM pelicula,
  6. INNER JOIN es_actor_pelicula ON
  7.   pelicula.titulo = es_actor_pelicula.tituloPelicula AND
  8.   pelicula.año = es_actor_pelicula.añoPelicula
  9. INNER JOIN es_director ON
  10.   pelicula.titulo = es_director.tituloPelicula AND
  11.   pelicula.año = es_director.añoPelicula
  12. INNER JOIN idioma_pelicula ON
  13.   pelicula.titulo = idioma_pelicula.tituloPelicula AND
  14.   pelicula.año = idioma_pelicula.añoPelicula
  15. INNER JOIN subtitulos_pelicula ON
  16.   pelicula.titulo = subtitulos_pelicula.tituloPelicula AND
  17.   pelicula.año = subtitulos_pelicula.añoPelicula
  18. INNER JOIN tiene_pelicula ON
  19.   pelicula.titulo= tiene_pelicula.tituloPelicula AND
  20.   pelicula.año = tiene_pelicula.añoPelicula
  21. INNER JOIN ubicacion_pelicula ON
  22.   pelicula.titulo = ubicacion_pelicula.tituloPelicula AND
  23.   pelicula.año = ubicacion_pelicula.añoPelicula
  24.   pelicula.titulo LIKE '%consulta%' OR
  25.   pelicula.año LIKE '%consulta%' OR
  26.   pelicula.pais LIKE '%consulta%' OR
  27.   pelicula.notas LIKE '%consulta%' OR
  28.   es_actor_pelicula.nombre LIKE '%consulta%' OR
  29.   es_director.nombre LIKE '%consulta%' OR
  30.   idioma_pelicula.idioma LIKE '%consulta%' OR
  31.   subtitulos_pelicula.subtitulos LIKE '%consulta%' OR
  32.   tiene_pelicula.productora LIKE '%consulta%' OR
  33.   ubicacion_pelicula.ubicacion LIKE '%consulta%'


Finalmente, puedes considerar el hacer un sólo catálogo tipo FULL TEXT con toda la información de tus tablas, en lugar de tener un modelo con 7 tablas... e implementar las funciones de búsqueda de texto completo. Dale un vistazo a esta liga:

http://dev.mysql.com/doc/refman/5.0/...xt-search.html

Saludos
Leo.