Rendimiento Full-Text

El rendimiento de las búsquedas full-text depende de varias variables de configuración de MySQL. Entender estas variables te permite ajustar el comportamiento de la búsqueda para tu caso de uso: desde la longitud mínima de palabra hasta la lista de stopwords y el tamaño del cache.

Longitud mínima de palabra

MySQL ignora palabras más cortas que un mínimo configurable:

-- Ver la longitud mínima para InnoDB
SHOW VARIABLES LIKE 'innodb_ft_min_token_size';
Variable_nameValue
innodb_ft_min_token_size3
-- Ver la longitud mínima para MyISAM
SHOW VARIABLES LIKE 'ft_min_word_len';
Variable_nameValue
ft_min_word_len4

Con el valor por defecto de InnoDB, palabras como "tv", "pc" o "ai" no se indexan. Si necesitas buscar palabras cortas, puedes reducir este valor en la configuración:

-- En my.cnf / my.ini:
-- [mysqld]
-- innodb_ft_min_token_size=2

Después de cambiar este valor, debes reconstruir los índices full-text:

-- Reconstruir el índice
ALTER TABLE productos DROP INDEX ft_productos;
CREATE FULLTEXT INDEX ft_productos ON productos (nombre, descripcion);

Longitud máxima de palabra

SHOW VARIABLES LIKE 'innodb_ft_max_token_size';
Variable_nameValue
innodb_ft_max_token_size84

Palabras más largas que 84 caracteres no se indexan. Rara vez necesitas cambiar este valor.

Stopwords

Las stopwords son palabras comunes que MySQL excluye del índice full-text porque aparecen con tanta frecuencia que no aportan valor en las búsquedas. Palabras como "the", "and", "is" en inglés.

-- Ver la tabla de stopwords de InnoDB
SELECT * FROM information_schema.INNODB_FT_DEFAULT_STOPWORD;
value
a
about
an
are
as
at
be
by
com
de
en
for
from
how
i
in
is
it
la
of
on
or
that
the
this
to
was
what
when
where
who
will
with
und
the
www

Las stopwords por defecto incluyen algunas palabras en español como "de", "en", "la". Sin embargo, la lista es principalmente en inglés.

Crear lista personalizada de stopwords

Para aplicaciones en español, puedes crear tu propia lista:

-- Crear tabla con stopwords personalizadas
CREATE TABLE mis_stopwords (
    value VARCHAR(30)
) ENGINE = InnoDB;
 
INSERT INTO mis_stopwords (value) VALUES
('el'), ('la'), ('los'), ('las'), ('un'), ('una'), ('unos'), ('unas'),
('de'), ('del'), ('al'), ('en'), ('con'), ('por'), ('para'),
('que'), ('es'), ('son'), ('se'), ('su'), ('sus'),
('y'), ('o'), ('pero'), ('como'), ('más'), ('muy'),
('este'), ('esta'), ('estos'), ('estas'),
('no'), ('si'), ('ya'), ('hay');
 
-- Configurar MySQL para usar tu lista
SET GLOBAL innodb_ft_server_stopword_table = 'tienda_mysql/mis_stopwords';

Después de cambiar la tabla de stopwords, debes reconstruir los índices full-text.

Desactivar stopwords

-- Usar una tabla vacía como stopwords desactiva el filtrado
CREATE TABLE stopwords_vacia (
    value VARCHAR(30)
) ENGINE = InnoDB;
 
SET GLOBAL innodb_ft_server_stopword_table = 'tienda_mysql/stopwords_vacia';

Variables de configuración

VariableValor por defectoDescripción
innodb_ft_min_token_size3Longitud mínima de palabra
innodb_ft_max_token_size84Longitud máxima de palabra
innodb_ft_server_stopword_table-Tabla de stopwords personalizada
innodb_ft_enable_stopwordONHabilitar/deshabilitar stopwords
innodb_ft_cache_size8000000Cache del índice en bytes
innodb_ft_sort_pll_degree2Paralelismo al construir el índice
innodb_ft_result_cache_limit2000000000Límite de cache de resultados

Optimizar el índice

Los índices full-text de InnoDB acumulan entradas eliminadas que no se purgan automáticamente:

-- Optimizar el índice full-text
OPTIMIZE TABLE productos;
TableOpMsg_typeMsg_text
tienda_mysql.productosoptimizestatusOK

OPTIMIZE TABLE purga las entradas eliminadas y reconstruye el índice. Ejecútalo periódicamente en tablas con muchas actualizaciones.

Recomendaciones

  1. Ajusta innodb_ft_min_token_size según tu caso de uso. Para español, 3 caracteres suele ser adecuado.

  2. Crea una lista de stopwords en español si tu contenido es principalmente en español.

  3. Ejecuta OPTIMIZE TABLE periódicamente en tablas con muchos INSERT/DELETE.

  4. No crees índices full-text innecesarios: cada índice consume memoria y ralentiza las escrituras.

  5. Usa índices full-text sobre múltiples columnas cuando la búsqueda debe abarcar varios campos.

Limpieza

DROP TABLE IF EXISTS mis_stopwords;
DROP TABLE IF EXISTS stopwords_vacia;

En el siguiente artículo veremos MATCH AGAINST, la sintaxis para realizar búsquedas full-text.

Escrito por Eduardo Lázaro