Actualmente estoy tratando de ejecutar algunas consultas contra un volcado de datos de los comentarios de Stack Overflow. Así es como se ve el esquema:
CREATE TABLE `socomments` (
`Id` int(11) NOT NULL,
`PostId` int(11) NOT NULL,
`Score` int(11) DEFAULT NULL,
`Text` varchar(600) NOT NULL,
`CreationDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`UserId` int(11) NOT NULL,
PRIMARY KEY (`Id`),
KEY `idx_socomments_PostId` (`PostId`),
KEY `CreationDate` (`CreationDate`),
FULLTEXT KEY `Text` (`Text`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
Ejecuté esta consulta en la tabla, y funcionó increíblemente lento (tiene 29 millones de filas, pero tiene un índice de texto completo):
SELECT *
FROM socomments
WHERE MATCH (Text) AGAINST ('"fixed the post"' IN BOOLEAN MODE)
Así que lo perfilé, cuyos resultados son:
|| Status || Duration ||
|| starting || 0.000058 ||
|| checking permissions || 0.000006 ||
|| Opening tables || 0.000014 ||
|| init || 0.000019 ||
|| System lock || 0.000006 ||
|| optimizing || 0.000007 ||
|| statistics || 0.000013 ||
|| preparing || 0.000005 ||
|| FULLTEXT initialization || 207.1112 ||
|| executing || 0.000009 ||
|| Sending data || 0.000856 ||
|| end || 0.000004 ||
|| query end || 0.000004 ||
|| closing tables || 0.000006 ||
|| freeing items || 0.000059 ||
|| logging slow query || 0.000037 ||
|| cleaning up || 0.000046 ||
Como puede ver, pasa mucho tiempo en la inicialización de FULLTEXT. ¿Esto es normal? Si no, ¿cómo lo arreglaría?
mysql
innodb
full-text-search
hichris123
fuente
fuente
id_group 2
yid_group 23
. Con esto, su búsqueda dentro de su tabla principal y limitar su consulta a los rangos de identificación 2.000 a 2.999 y 23.000 a 23.999. Por supuesto, el segundo obtendrá más resultados según sea necesario a medida que mezcle todos los comentarios creando nuevas combinaciones de palabras clave, pero finalmente debería acelerar todo. Por supuesto, duplica el uso de espacio en disco. Los nuevos comentarios deben CONCATARSE a la tabla de grupo.Respuestas:
Otros han encontrado esto como una situación problemática.
Dado que la documentación de MySQL es muy breve en este estado de subproceso
su único recurso sería hacer una preparación con menos datos. Cómo ?
SUGERENCIA # 1
Mire su consulta nuevamente. Está seleccionando todas las columnas. Refactorizaría la consulta para recopilar solo las columnas de identificación
socomments
. Luego, une esos identificadores recuperados a lasocomments
mesa.Esto podría producir un plan EXPLICAR más feo, pero creo que el perfil cambiará para mejor. La idea básica es: si tiene una búsqueda FULLTEXT agresiva, haga que recopile la menor cantidad de datos durante esa
FULLTEXT initialization
fase, reduciendo así el tiempo.Lo he recomendado muchas veces antes
May 14, 2012
: consulta lenta con texto completo y combinación izquierdaMar 18, 2012
: ¿Por qué LIKE es más de 4 veces más rápido que MATCH ... CONTRA un índice FULLTEXT en MySQL?Jan 26, 2012
: Mysql fulltext search optimización my.cnf :Oct 25, 2011
: Índice FULLTEXT ignorado en MODO BOOLEANO con condicional 'número de palabras'SUGERENCIA # 2
Asegúrese de configurar las opciones FULLTEXT basadas en InnoDB, no las de MyISAM. Las dos opciones que debe preocupar son
Piensa un momento en ello. El campo de texto es VARCHAR (600). Digamos que el promedio es de 300 bytes. Tienes 29,000,000 millones de ellos. Eso sería un poco de 8GB. Tal vez aumentar innodb_ft_cache_size e innodb_ft_total_cache_size también puede ayudar.
Asegúrese de tener suficiente RAM para los búferes InnoDB FULLTEXT más grandes.
DARLE UNA OPORTUNIDAD !!!
fuente
SELECT B.* FROM (SELECT id FROM socomments WHERE MATCH (Text) AGAINST ('+"fixed the post"' IN BOOLEAN MODE)) A LEFT JOIN socomments B USING (id);
y vea si hace la diferencia.A leading or trailing plus sign indicates that this word must be present in each row that is returned. InnoDB only supports leading plus signs.
En su caso particular,fixed the post
debe existir la frase exacta .Si está utilizando índices InnoDB FULLTEXT, las consultas a menudo se bloquean en el estado "Inicialización FULLTEXT" si está consultando una tabla que tiene una gran cantidad de filas eliminadas. En la implementación FULLTEXT de InnoDB, las filas eliminadas no se eliminan hasta que se ejecuta una operación OPTIMIZE posterior contra la tabla afectada. Ver: https://dev.mysql.com/doc/refman/5.6/en/innodb-fulltext-index.html
También se puede inspeccionar el número de registros eliminados pero no purgados al consultar information_schema.innodb_ft_deleted
Para resolver esto, regularmente se debe ejecutar OPTIMIZE TABLE en tablas con índices InnoDB FULLTEXT.
fuente
innodb_optimize_fulltext_only=1
y unaOPTIMIZE
tabla realmente se encarga de las filas eliminadas "en espera"? dba.stackexchange.com/questions/174486/…Hay un error confirmado en MySQL (el DOCID eliminado no se mantiene durante la OPTIMIZACIÓN de las tablas InnoDB FULLTEXT ) que reduce el rendimiento de los depósitos bajo cargas pesadas de eliminación (sin reconstruir la tabla desde cero).
Relacionados .
fuente
Los índices de texto completo en MySQL no están diseñados para admitir grandes cantidades de datos, por lo que la velocidad de búsqueda desciende bastante rápido a medida que crece su conjunto de datos. Una de las soluciones es utilizar motores de búsqueda externos de texto completo como Solr o Sphinx, que ha mejorado la funcionalidad de búsqueda (ajuste de relevancia y soporte de búsqueda de frases, facetas integradas, fragmentos, etc.) sintaxis de consulta extendida y una velocidad mucho más rápida en la mitad de -grandes conjuntos de datos.
Solr se basa en la plataforma Java, por lo que si ejecuta una aplicación basada en Java será una elección natural para usted, Sphinx está escrito en C ++ y actúa como un demonio de la misma manera que MySQL. Tan pronto como alimente a un motor externo con los datos que desea buscar, también puede mover algunas consultas fuera de MySQL. No puedo decirte qué motor es mejor en tu caso, utilizo principalmente Sphinx y aquí hay un ejemplo de uso: http://astellar.com/2011/12/replacing-mysql-full-text-search-with-sphinx/
fuente