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

Intento optimizar una consulta sql lenta

Estas en el tema de Intento optimizar una consulta sql lenta en el foro de Mysql en Foros del Web. Buenas tardes! Tengo un problemilla con una consulta sql y es que es demasiado lenta. No tengo mucha experiencia en el campo y espero que ...
  #1 (permalink)  
Antiguo 04/09/2012, 16:26
 
Fecha de Ingreso: marzo-2008
Mensajes: 15
Antigüedad: 16 años, 8 meses
Puntos: 1
Intento optimizar una consulta sql lenta

Buenas tardes!
Tengo un problemilla con una consulta sql y es que es demasiado lenta. No tengo mucha experiencia en el campo y espero que alguien de por aquí pueda darme algún consejo útil.

Es una base de datos de películas y el objetivo de la consulta es hacer una búsqueda general de películas en todas las tablas a partir de un texto que escriba un usuario.
Es decir, que si el usuario escribe 'algo', aparezcan todas las pelis que tengan en el titulo 'algo', pero también todas las pelis que tengan asociadas algún actor que contenga 'algo' y así con todos los datos.

La consulta es esta:

Código:
SELECT DISTINCT pelicula.titulo,pelicula.año,pelicula.duracion,pelicula.pais 
FROM pelicula,es_actor_pelicula,es_director,idioma_pelicula,subtitulos_pelicula,tiene_pelicula,ubicacion_pelicula
WHERE 
(pelicula.titulo REGEXP '.*consulta.*') 
OR (pelicula.año REGEXP '.*consulta.*') 
OR (pelicula.pais REGEXP '.*consulta.*') 
OR (pelicula.notas REGEXP '.*consulta.*') 
OR (es_actor_pelicula.nombre REGEXP '.*consulta.*' AND pelicula.titulo= es_actor_pelicula.tituloPelicula AND pelicula.año = es_actor_pelicula.añoPelicula) 
OR (es_director.nombre REGEXP '.*consulta.*' AND pelicula.titulo= es_director.tituloPelicula AND pelicula.año = es_director.añoPelicula) 
OR (idioma_pelicula.idioma REGEXP '.*consulta.*' AND pelicula.titulo= idioma_pelicula.tituloPelicula AND pelicula.año = idioma_pelicula.añoPelicula) 
OR (subtitulos_pelicula.subtitulos REGEXP '.*consulta.*' AND pelicula.titulo= subtitulos_pelicula.tituloPelicula AND pelicula.año = subtitulos_pelicula.añoPelicula) 
OR (tiene_pelicula.productora REGEXP '.*consulta.*' AND pelicula.titulo= tiene_pelicula.tituloPelicula AND pelicula.año = tiene_pelicula.añoPelicula) 
OR (ubicacion_pelicula.ubicacion REGEXP '.*consulta.*' AND pelicula.titulo= ubicacion_pelicula.tituloPelicula AND pelicula.año = ubicacion_pelicula.añoPelicula)
Ya sé que son muchas cosas para una misma consulta.... pero con pocos datos iba bien, hasta que metí más de 10 películas :(
Espero que alguien pueda echarme una mano para optimizarla, porque hace poco que trabajo con sql.
Muchas gracias!! :D
  #2 (permalink)  
Antiguo 05/09/2012, 08:18
Colaborador
 
Fecha de Ingreso: enero-2007
Ubicación: México
Mensajes: 2.097
Antigüedad: 17 años, 11 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.

Etiquetas: intento, lenta, select, sql, tabla, campos
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 05:46.