3 de septiembre de 2011

MySQL FULLTEXT. Indexando texto para busquedas


Imaginemos que en esas noches de insomnio dedicadas a las máquinas hemos programado un spider en Perl o PHP que hora a hora ha visitado varios milloncejos de webs, scrapeando y almacenando código html en una base de datos MySQL, ...es un suponer!!!
Y pasado el tiempo llega el momento de hacer alguna busqueda en la ingente cantidad de código html almacenado en la MySQL.

Siqueremos buscar la palabra "pepe" en el campo que almacena el html:

SELECT * FROM tabla WHERE html LIKE '%pepe%';

... y la busqueda se realiza pero es enormemente lenta.

La razón es que motor de búsqueda tienen que revisar todos los interminables campos de la interminable base de datos.

Incluso he probado este tipo de búsquedas sobre bases de datos con campos extensos de texto en diferentes máquinas (AMD geode 500MHz 500MB RAM y Pentiun 2800MHz 5ooMB RAM) y el tiempo de consulta es curiosamente el mismo!!!.
Esto me dio a entender que algo estaba haciendo mal.



Como vemos para mejorar las búsquedas sobre campos extensos de texto hay varios métodos y herramientas que permiten hacer búsquedas eficientes en este tipo de bases de datos:
Ref: Practical Full Text Search with MySQL
(aqui hay links a otras interesantes presentaciones sobre el tema)

Voy a probar MySQL FULLTEXT ya que esta integrada en MySQL y aprovecho la estructura existente de la base de datos.

MySQL FullText HowTo

Por lo que veo FULLTEXT crea un índice que agiliza la búsqueda en campos de texto.
Este índice se puede generar en tablas nuevas o preexistent es usando:

CREATE TABLE ... FULLTEXT :
CREATE TABLE table_name(
‘column1’ data_type,
‘column2’ data_type,
...
PRIMARY_KEY(‘key_column’),
FULLTEXT (‘column_name1’,’column_name2’,..)
) ENGINE=MyISAM;
ALTER TABLE ... FULLTEXT:
ALTER TABLE table_name
ADD FULLTEXT(column_name1, column_name2,…)

Como ya tenemos la base de datos MySQL hecha y llenita de información, generamos el índice mediante ALTER TABLE ... FULLTEXT ...

ALTER TABLE spider01 ADD FULLTEXT (`html`,`mtag_keywords`,`mtag_descript`,`mtag_titulo`,`webtitulo`)
Su consulta se ejecutó con éxito ( La consulta tardó 384.8188 seg )

Eliminar campos del indice FULLTEXT
Para eliminar campos del indice FullText creado:

ALTER TABLE "table" DROP INDEX "campo1, campo2,...";


MySQL FULLTEXT con phpMyadmin:
Como no podría ser de otra manera todo esto se puede hacer con phpMyadmin a golpe de ratón. Este programa no deja de maravillarme.


Búsquedas con MySQL FULLTEXT:
En este punto, una vez que tenemos preparada nuestra base de datos para hacer busquedas con FULLTEXT, es imprescindible revisar las inmensas capacidades de esta herramienta de MySQL.

La búsqueda no es sensible a las mayúsculas.

De forma general tenemos la búsqueda mas básica:
SELECT * FROM spider01 WHERE MATCH html AGAINST '%pepe%';

Aqui vemos una mas que notable mejoría en tiempo de búsqueda:


Los modos de búsqueda son:

IN NATURAL LANGUAGE
  • Trata el texto como una frase.
  • Si no se indica nada se usa el Natural Lenguage por defecto.
  • Ordena los registros por relevancia.
  • Las palabras con menos de 4 letras son ignoradas. Esto se puede configurar con las variables: ft_min_word_len y ft_max_word_lenFullText.
  • Las palabras de la lista de StopWords son ignoradas. Esto se puede inactivar o modificar cambiando la variable ft_stopword_file.
  • Las palabras que aparecen en mas del 50% de los registros es varemada con un valor 0. Esto es bueno en grandes bases de datos pero malo en pequeñas.
Ref.:

IN BOOLEAN MODE
No ordena el resultado por relevancia
No usa la lista de StopWords.
Combina las palabras de la busqueda segun los operadores lógicos indicados.
Por defecto los combina con OR.


WITH QUERY EXPANSION


Reindexando la tabla
Caundo se cambia el ínice o las varibles de FULLTEX hay que reindexar:

REPAIR TABLE tbl_name QUICK;



No hay comentarios:

Publicar un comentario