26 de Agosto, 2004

Búsquedas más o menos complejas

Las búsquedas en blackshell son un rato lentas. No es que hayan muchos registros en la base de datos, ni tampoco es definitivo que la máquina sea un Pentium a 100MHz (aunque algo tiene que ver, claro).

Resulta que las búsquedas se realizan también en los comentarios, y el query queda algo complicado. Tal que así:

select tblNoticia.id, tblNoticia.fecha, tblNoticia.titular 
from tblNoticia, tblComentario
where tblNoticia.titular like "%X%" or
tblNoticia.texto like "%X%" or 
(
 tblComentario.idNoticia=tblNoticia.id and 
 (
  tblComentario.titular like "%X%" or
  tblComentario.texto like "%X%"
 )
)
group by tblNoticia.id order by fecha desc

La X marca el lugar, vamos... que es la cadena a buscar :P. Además he indentado los paréntesis para que quede más claro.

De esta forma busco la cadena en todas las noticias y en sus comentarios asociados, y el resultado es una sola vista de noticias.

No se si se puede hacer más simple, pero vamos a mi no se me ha ocurrido cómo... y a blackshell le cuesta un poquito :).

Actualización: Hasta que no encuentre una solución, dejo de buscar en los comentarios. La misma búsqueda tarda 34 segundos incluyendo los comentarios y uno (o instantáneo, no soy tan bueno con el crono :D) sin incluirlos. La espera del query complejo no es aceptable, aunque se pierda mucha calidad con el simple. Ay si tuviera más micro...

Anotación por Juan J. Martínez.

Hay 5 comentarios

Gravatar

Hola!!
A ver, te comento, la query está bastante mal. Para comenzar, estoy segura de que no te funcionará, entre otras cosas porque haces un group by con un campo, y en la select metes 3. Esto no es posible, a no ser que los 2 campos que no metes en el group by (fecha y titular) le pongas un max, min, etc...
Además introduces 2 tablas en el from, y luego solo las cruzas en un or, esto no es correcto. Si metes 2 tablas, las tienes que utilizar y cruzar. Si no quieres meter 2 tablas, lo suyo es que lo metieras a través de una subselect, o bien a través de un union.

por María, en 2004-08-27 18:21:33

Gravatar

Tendrías que indexar (si es posible) todos los campos que buscas con like, ya que el like es muyyyyy lento.

Podría quedarte así con un union:

select distinct
tblNoticia.id,
tblNoticia.fecha,
tblNoticia.titular
from
(
select
tblNoticia.id,
tblNoticia.fecha,
tblNoticia.titular
from
tblNoticia
where
tblNoticia.titular like '%X%' or
tblNoticia.texto like '%X'
union
select
tblNoticia.id,
tblNoticia.fecha,
tblNoticia.titular
from
tblNoticia,
tblComentario
where
tblComentario.idNoticia=tblNoticia.id and
(
tblComentario.titular like '%X%' or
tblComentario.texto like '%X%'
)
)
order by tblNoticia.fecha;

por María, en 2004-08-27 18:23:37

Gravatar

Yo te aconsejo que lo busques cruzando todo y teniendo los campos indexados (tal y como te he comentado antes). Sería algo así:
select
tblNoticia.id,
tblNoticia.fecha,
tblNoticia.titular
from
tblNoticia,
tblComentario
where
tblComentario.idNoticia=tblNoticia.id and
(
tblNoticia.titular like '%X%' or
tblNoticia.texto like '%X' or
tblComentario.titular like '%X%' or
tblComentario.texto like '%X%'
)
order by tblNoticia.fecha;

No tengo claro si todas las noticias tienen comentarios. Si fuera así lo comentas y te digo, habría varias opciones para eso.

Espero reducir tus tiempos de búsqueda. El que espera, desespera, ¿no?

Un saludo.

por Maria, en 2004-08-27 18:28:26

Gravatar

Yo también opté por no buscar en los comentarios, porque mi blog ya hace demasiadas queries a la base de datos :( ... a ver si lo "aligero" un poco...

:(

Saludos...

PS: María, muy interesantes tus anotaciones :)

por Toad, en 2004-08-28 21:38:17

Gravatar

Maria: Y perfectamente, salvo que en el Pentium 100 es lento. Lista las noticias en las que se encuentre el término a buscar en su cuerpo o en el cuerpo del comentario. Quizás el group by de MySQL no se comporta como piensas.

Tu primera respuesta no me sirve, aunque parece correcta (no se si lo es). MySQL 3.x, que es lo que uso de sgbd, aun no soportaba subqueries al 100% (solo casos muy limitados).

Y tu segunda propuesta es claramente incorrecta para mis requerimientos. No realizará la búsqueda en noticias que no tengan comentarios (tblComentario.idNoticia = tblNoticia.id siempre sería falso y nunca llegaría a los like).

Resumiendo: sin subqueries la cosa se complica mucho :(

por Juanjo, en 2004-08-29 20:08:56

Los comentarios están cerrados: los comentarios se cierran automáticamente una vez pasados 30 días. Si quieres comentar algo acerca de la anotación, puedes hacerlo por e-mail.