Prólogo
- Solo los motores de almacenamiento Innodb y myisam pueden usar la indexación de texto completo (innodb admite la indexación de texto completo a partir de mysql5.6)
- Los campos Char, varchar, text type pueden crear índice de texto completo (tipo de índice de texto completo)
- El índice de texto completo se basa en palabras clave. Para distinguir las diferentes palabras clave, debemos utilizar la segmentación de palabras (palabra clave)
- Las palabras en inglés están separadas por espacios y comas; la segmentación de palabras en chino es inconveniente (una oración no sabe distinguir palabras clave diferentes)
- El ngram analizador de segmentación de palabras incorporado admite chino, japonés y coreano (frases que dividen oraciones en números fijos)
- Al escribir una gran cantidad de datos en una tabla, es más rápido crear un índice de texto completo después de escribir los datos (lo que reduce la sobrecarga de mantener el índice)
- El índice invertido (una estructura de datos) del principio de indexación de texto completo, que generalmente usa una matriz asociativa para almacenar el mapeo entre palabras y la ubicación del documento en la tabla auxiliar
Para utilizar
Use MATCH () ... CONTRA para buscar
match () significa que se busca en la columna, contra significa que la cadena a buscar es
Vea la segmentación de palabras predeterminada (use estas palabras para distinguir diferentes palabras clave); también puede personalizar la segmentación de palabras para usar estas palabras para distinguir diferentes palabras clave SELECT * FROM information_schema.INNODB_FT_DEFAULT_STOPWORD;
Como
Tres tipos de métodos de búsqueda de texto completo.
búsqueda en lenguaje natural
Verifique pasando una cadena específica a través de MATCH CONTRA, de la manera predeterminada
búsqueda booleana
Agregar operadores a la cadena recuperada, como "+" significa que debe incluirse, "-" no contiene, "*" significa comodín, incluso si la cadena pasada es pequeña o aparece en la palabra de detención, no se filtrará
búsqueda de expansión de consultas
La cadena de búsqueda se usa para realizar una búsqueda en lenguaje natural, luego las palabras de la línea más relevante devuelta por la búsqueda se agregan a la cadena de búsqueda, y la búsqueda se realiza nuevamente, la consulta devolverá la línea de la segunda búsqueda
Parámetros relacionados
Configurar parámetros relacionados
innodb_ft_min_token_size tiene un valor predeterminado de 3, lo que indica un mínimo de 3 caracteres como palabra clave, aumentar el valor puede reducir el tamaño del índice de texto completo
innodb_ft_max_token_size tiene un valor predeterminado de 84, lo que significa que se puede utilizar un máximo de 84 caracteres como palabra clave. Limitar este valor puede reducir el tamaño del índice de texto completo
El tamaño predeterminado de ngram_token_size es 2, lo que significa que se usan 2 caracteres como palabra clave del tokenizer incorporado. Por ejemplo, para crear un índice de texto completo de "abcd", las palabras clave son 'ab', 'bc', 'cd'
Cuando se utiliza el analizador de segmentación de palabras ngram, innodb_ft_min_token_size e innodb_ft_max_token_size no son válidos
Tenga en cuenta que ninguno de estos tres parámetros puede modificarse dinámicamente. Si modifica estos parámetros, debe reiniciar el servicio MySQL y restablecer el índice de texto completo
Pruebe el motor innodb utilizando el índice de texto completo
Listo
1. Objetivo
- Pregunte si un artículo contiene una determinada palabra clave; la cantidad de veces que una serie de artículos aparece una determinada palabra clave
- Compruebe si el título del artículo contiene una palabra clave
2. Configure los siguientes parámetros para reducir la presión de E / S del disco
SET GLOBAL sync_binlog=100;
SET GLOBAL innodb_flush_log_at_trx_commit=2;
3. Importe datos de 1kw para probar el índice de texto completo
La búsqueda en línea de la fuente de datos
https://pan.baidu.com/s/1aaB1R3bkBGZRMEx0o6T61w Código de extracción: 60l7
4. La estructura de una tabla de artículos.
Utilice los datos de prueba de importación de subprocesos múltiples de myloader
-- 先把测试数据进行解压
tar -zxf mydumper_dump_article.tar.gz
time myloader -u $user -p $passwd -S $socket -t 32 -d /datas/dump_article -v 3
5. Después de importar los datos, el volumen total de datos y el tamaño del archivo de datos y el archivo de índice
SELECT COUNT(*) FROM `article`;
+----------+
| COUNT(*) |
+----------+
| 10000000 |
+----------+
1 row in set (7.85 sec)
SELECT table_name, CONCAT(FORMAT(SUM(data_length) / 1024 / 1024,2),'M') AS dbdata_size, CONCAT(FORMAT(SUM(index_length) / 1024 / 1024,2),'M') AS dbindex_size, CONCAT(FORMAT(SUM(data_length + index_length) / 1024 / 1024 / 1024,2),'G') AS `db_size(G)`, AVG_ROW_LENGTH,table_rows,update_time FROM information_schema.tables WHERE table_schema = DATABASE() and table_name='article';
+------------+-------------+--------------+------------+----------------+------------+---------------------+
| table_name | dbdata_size | dbindex_size | db_size(G) | AVG_ROW_LENGTH | table_rows | update_time |
+------------+-------------+--------------+------------+----------------+------------+---------------------+
| article | 3,710.00M | 1,003.00M | 4.60G | 414 | 9388739 | 2019-07-05 15:31:37 |
+------------+-------------+--------------+------------+----------------+------------+---------------------+
Use el método predeterminado para crear un índice de texto completo
1. La tabla ya tiene un campo de palabras clave (una breve descripción del contenido del artículo) y utiliza "," como tokenizer
2. Busque una palabra clave cuando no construya un índice de texto completo
Se requiere escaneo completo de la tabla
3. Cree un índice de texto completo en el campo de palabras clave (con, como segmentación de palabras)
Establezca innodb_ft_min_token_size en el archivo de configuración my.cnf y reinicie el servicio MySQL (mínimo dos caracteres como palabra clave, tres caracteres predeterminados como palabra clave)
[mysqld]
innodb_ft_min_token_size=2
3.1 Establecer palabras clave personalizadas (es decir, segmentación de palabras)
USE mysql;
CREATE TABLE my_stopwords(VALUE VARCHAR(30)) ENGINE = INNODB;
INSERT INTO my_stopwords(VALUE) VALUE (',');
SET GLOBAL innodb_ft_server_stopword_table = 'mysql/my_stopwords';
~
SHOW GLOBAL VARIABLES WHERE Variable_name IN('innodb_ft_min_token_size','innodb_ft_server_stopword_table');
+---------------------------------+--------------------+
| Variable_name | Value |
+---------------------------------+--------------------+
| innodb_ft_min_token_size | 2 |
| innodb_ft_server_stopword_table | mysql/my_stopwords |
+---------------------------------+--------------------+
3.2 Crear un índice de texto completo
alter table article add fulltext index idx_full_keyword(keywords);
* [ ] Query OK, 0 rows affected, 1 warning (1 min 27.92 sec)
* [ ] Records: 0 Duplicates: 0 Warnings: 1
3.3 El espacio restante en el disco debe ser suficiente, la tabla original es 4.6G y el disco restante 5.7G, agregando índice de texto completo también fallará
3.4 Use el índice de texto completo creado para consultar el número de apariciones de una palabra clave
El tiempo de respuesta de la consulta se ha mejorado enormemente, solo 0.05s; usando palabras clave como '% Fashion%' toma 7.56s. Lectura recomendada: prácticas de optimización del rendimiento de MySQL (muy completo y que vale la pena recopilar)
3.5 Si necesita hacer coincidir varias palabras clave al mismo tiempo, utilice la búsqueda de texto completo booleano
Número de registros que coinciden exactamente con "Sanlitun, Beijing"
select count(*) from article where match(keywords) against('+三里屯,北京' in boolean mode);
+----------+
| count(*) |
+----------+
| 1 |
+----------+
1 row in set (0.06 sec)
Indica el número de registros que coinciden con "Sanlitun" o "Beijing"
select count(*) from article where match(keywords) against('三里屯,北京');
+----------+
| count(*) |
+----------+
| 8 |
+----------+
1 row in set (0.06 sec)
3.6 Después de crear un índice de texto completo, se crearán algunos otros archivos
96K Jul 5 16:30 FTS_00000000000000a7_00000000000000c0_INDEX_1.ibd96K Jul 5 16:30 FTS_00000000000000a7_00000000000000c0_INDEX_2.ibd96K Jul 5 16:30 FTS_00000000000000a7_00000000000000c0_INDEX_3.ibd96K Jul 5 16:30 FTS_00000000000000a7_00000000000000c0_INDEX_4.ibd128K Jul 5 16:30 FTS_00000000000000a7_00000000000000c0_INDEX_5.ibd256K Jul 5 16:30 FTS_00000000000000a7_00000000000000c0_INDEX_6.ibd96K Jul .Cuatro
- Los primeros 6 indican índice invertido (tabla de índice auxiliar)
- Los elementos 7 y 8 indican la ID del documento (DOC_ID) que contiene el documento eliminado, y sus datos se están eliminando actualmente del índice de texto completo
- La novena información que indica el estado interno del índice FULLTEXT
- Los documentos 10 y 11 contienen documentos que se han eliminado pero sus datos no se han eliminado del índice de texto completo
Cree un índice de texto completo utilizando el analizador de segmentación de palabras ngram
1. Establezca un índice de texto completo en el campo de título (el campo no tiene una segmentación de palabras de palabras vacías fija, use un analizador de segmentación de palabras ngram)
Debe establecer ngram_token_size en el archivo de configuración my.cnf (el valor predeterminado es 2, 2 caracteres como palabras clave ngram) y reiniciar el servicio mysql
Use el 2 por defecto aquí
select title from article limit 10;
+------------------------------------------------------------------------------+
| title |
+------------------------------------------------------------------------------+
| worth IT |
|Launchpad 江南皮革厂小show |
|Raw 幕后罕见一刻 “疯子”被抬回后台 |
|Raw:公子大骂老爸你就是个绿茶 公子以一打四 |
|四组30平米精装小户型,海量图片,附户型图 |
|夜店女王性感烟熏猫眼妆 |
|大秀哥重摔“巨石”强森 |
|少女时代 崔秀英 服饰科普 林允儿 黄美英 金泰妍 郑秀晶 |
|德阳户外踏青,花田自助烧烤 |
+------------------------------------------------------------------------------+
2. Cree un índice de texto completo en el campo del título.
alter table article add fulltext index ft_index_title(title) with parser ngram;
Query OK, 0 rows affected (3 min 29.22 sec)
Records: 0 Duplicates: 0 Warnings: 0
3. Se creará un índice invertido (cuanto más largo sea el campo de título, mayor será el índice invertido creado)
112M Jul 5 21:46 FTS_00000000000000a7_00000000000000cd_INDEX_1.ibd28M Jul 5 21:46 FTS_00000000000000a7_00000000000000cd_INDEX_2.ibd20M Jul 5 21:46 FTS_00000000000000a7_00000000000000cd_INDEX_3.ibd140M Jul 5 21:46 FTS_00000000000000a7_00000000000000cd_INDEX_4.ibd128M Jul 5 21:46 FTS_00000000000000a7_00000000000000cd_INDEX_5.ibd668M Jul 5 21:46 FTS_00000000000000a7_00000000000000cd_INDEX_6.ibd
4. Busque una palabra clave de título sin establecer un índice de texto completo
5. Use un índice de texto completo para buscar una palabra clave
El tiempo de respuesta ha mejorado considerablemente.
6. Tenga en cuenta que cuando el número de palabras clave buscadas es mayor que 2 (ngram_token_size define el tamaño), se producirán inconsistencias
Búsqueda ordinaria, el número real de registros donde aparece la palabra clave es 6
Búsqueda de texto completo, el número de registros con palabras clave es 9443
El número de registros donde aparece realmente la palabra clave es 1
El número de registros donde aparece la palabra clave en la búsqueda de texto completo es 3202
Conclusión
Cuando hay un participio fijo de palabra de parada (carácter de espacio en inglés, "," "-", etc.) en un campo de mysql, se establece un índice de texto completo para el campo, que puede buscar rápidamente información de registro relevante de una determinada palabra clave y realizar una búsqueda simple Efecto del motor
Cuando un campo mysql no tiene una segmentación de palabras de palabra de parada fija, use el ngram analizador incorporado para dividir el valor del campo en un número fijo de palabras clave (el tamaño definido por ngram_token_size) para una búsqueda rápida; cuando el número de caracteres de la palabra clave buscada no es igual al tamaño definido por ngram_token_size, lo hará Hay un problema que es inconsistente con la situación actual.
El índice de texto completo se puede buscar rápidamente, y también existe la sobrecarga de mantener el índice; cuanto mayor sea la longitud del campo, mayor será el índice de texto completo creado, lo que afectará el rendimiento de la declaración DML. Se puede usar un motor de búsqueda de texto completo dedicado ES para hacer esto