ubicacion mostrar las guardar guardan donde datos configurar carpeta cambiar bases archivos archivo mysql sql unix search full-text-search

mostrar - Mejora de la búsqueda de ruta de archivo en mysql



guardar archivos pdf en mysql (6)

Tengo varios millones de nombres de archivo que necesito buscar. Se ven así:

LG_MARGINCALL_HD2CH_127879834_EN.mov

Si alguien busca cualquiera de los siguientes, debe coincidir:

  • margen
  • llamada de margen
  • llamada de margen mov
  • margin call hd en
  • margin call hd en mov

Lo que estoy usando actualmente es una búsqueda mysql% LIKE%. Algo como:

SELECT filename FROM path WHERE filename LIKE ''%margin%'' AND filename LIKE ''%mov%''

Es extremadamente lento (puede tomar hasta diez segundos para una búsqueda). Tenga en cuenta que sí funciona .

¿Cuál sería una mejor manera de hacer la búsqueda anterior? Ya sea usando mysql u otro programa.


Tu estrategia de búsqueda es, como habrás notado, lenta. Es lento porque

LIKE ''%something%''

tiene que escanear la tabla para encontrar coincidencias. Los signos de% iniciales en búsquedas LIKE son una excelente manera de arruinar el rendimiento.

No sé cuántas columnas hay en su tabla de path . Si hay muchas columnas , puede hacer dos cosas rápidas para mejorar el rendimiento:

  1. deshacerse de SELECT * y enumerar los nombres de las columnas que desea en su conjunto de resultados.
  2. cree un índice compuesto que consista en su columna de filename de filename seguido de las otras columnas que necesita recuperar.

(Esto no ayudará si solo tiene unas pocas columnas en su tabla).

No puede usar FULLTEXT paquete de software FULLTEXT buscando esto, porque está diseñado para texto de idioma.

Si tuviera que hacer que esto funcionara rápido para la producción, haría esto:

Primero, cree una nueva tabla llamada "searchterm" que contenga

filename_id INT the id number of a row in your path table searchterm VARCHAR(20) a fragment of a filename.

Segundo, escriba un programa que lea los valores de filename filename_id y filename , e inserte un grupo de filas diferentes para cada uno en searchterm . Para el elemento que ha mostrado, los valores deberían ser:

LG_MARGINCALL_HD2CH_127879834_EN.mov (original) LG MARGINCALL HD2CH 127879834 EN mov (split on punctuation) HD 2 CH (split on embedded numerics) MARGIN CALL (split on an app-specific list of words)

Por lo tanto, tendría un montón de entradas en su tabla de búsqueda, todas con el mismo valor de filename_id y muchos trozos de texto diferentes.

Finalmente, al buscar puedes hacer esto.

SELECT path.id, path.filename, path.whatever, COUNT(DISTINCT searchterms.term) AS termcount FROM path JOIN searchterm ON path.filenanme_id = search.filename_id WHERE searchterm.term IN (''margin'',''call'',''hd'',''en'', ''mov'') GROUP BY path.id, path.filename, path.whatever ORDER BY path.filename, COUNT(DISTINCT searchterms.term) DESC

Esta pequeña consulta encuentra todos los fragmentos coincidentes con lo que está buscando. Devuelve varios nombres de archivo y los presenta en orden de lo que coincide con la mayoría de los términos.

Lo que estoy sugiriendo es que crees tu propio sistema de búsqueda de texto completo, parcial, específico de la aplicación. Si realmente tiene varios millones de archivos multimedia, seguramente vale la pena su esfuerzo.


Deje de usar la instrucción like en su lugar use match () y use un índice de texto completo para su columna de búsqueda y su tabla debe ser una de MYISAM (no sé si lo es o no)



Sugiero 2 cosas para intentar un mejor rendimiento. El primero es usar la palabra clave EXPLAIN delante de select . Esto puede brindarle alguna ayuda sobre el lento rendimiento de la consulta. Pero creo que no será de mucha ayuda. Lo segundo es usar REGEXP . Un ejemplo de todos estos:

EXPLAIN SELECT filename FROM path WHERE filename LIKE REGEXP ''^.*MAR{1}.*mov{1}''

pero debes buscar un poco más para optimizar la expresión regular.


Esto podría ser más rápido que usar AND :

SELECT filename FROM path WHERE filename LIKE ''%margin%call%hd%en%mov%''

Pero tener un "%" en el inicio de la cadena siempre lo hará lento.

Debería usar un índice de búsqueda de texto completo en el campo, y luego usar algo como:

SELECT filename FROM path WHERE MATCH(filename) AGAINST(''+margin +call +hd +en +mov'' IN BOOLEAN MODE);


Parece claro que necesita la funcionalidad de búsqueda de texto completo .

Existen múltiples soluciones que pueden responder a esto, una de las mejores en este momento es Elastic Search .

Tiene todas las capacidades para manejar la búsqueda de texto completo en tiempo real. Y va más allá de esto proporcionando sugerencias automáticas, autocompletar, etc.

Y es de código abierto.