2010-03-16 43 views
30

Si su objetivo es comprobar si existe una cadena en una columna MySQL (de tipo 'varchar', 'text', 'blob', etc.) ¿cuál de las siguientes opciones es más rápida/más eficiente/mejor de usar, y por qué?¿Qué es más rápido, INSTR o LIKE?

O, ¿hay algún otro método que encabece alguno de estos?

INSTR(columnname, 'mystring') > 0 

vs

columnname LIKE '%mystring%' 
+2

Habilitación de un índice de búsqueda de texto completo puede ser más rápido si las cadenas de texto son largas – kibibu

+0

'column regexp 'mystring '' suele ser más rápido que – Seth

+0

Su pregunta tiene al menos '5' votos para la etiqueta [tag: like-operator]. ¿Podría solicitar amablemente que sugiera [tag: sql-like] como [sinónimo] (http://stackoverflow.com/tags/like-operator/synonyms)? – Kermit

Respuesta

45

búsquedas FULLTEXT son absolutamente va a ser más rápido, como kibibu se señala en los comentarios anteriores.

Sin embargo:

mysql> select COUNT(ID) FROM table WHERE INSTR(Name,'search') > 0; 
+-----------+ 
| COUNT(ID) | 
+-----------+ 
|  40735 | 
+-----------+ 
1 row in set (5.54 sec) 

mysql> select COUNT(ID) FROM table WHERE Name LIKE '%search%'; 
+-----------+ 
| COUNT(ID) | 
+-----------+ 
|  40735 | 
+-----------+ 
1 row in set (5.54 sec) 

En mis pruebas, realizan exactamente el mismo. Ambos son insensibles a las mayúsculas y generalmente realizan escaneos de tabla completa, un no-no general cuando se trata de MySQL de alto rendimiento.

A menos que usted está haciendo una búsqueda de prefijo en una columna indexada:

mysql> select COUNT(ID) FROM table WHERE Name LIKE 'search%'; 
+-----------+ 
| COUNT(ID) | 
+-----------+ 
|   7 | 
+-----------+ 
1 row in set (3.88 sec) 

En cuyo caso, la única LIKE con un comodín sufijo es mucho más rápido.

+10

1 para realmente hacer el experimento!Demasiado rendimiento "sabiduría" se basa en el instinto – kibibu

10

En el caso de una "wilcard frontal" (es decir, un predicado "LIKE '% ...'" como parece ser el caso aquí, INSTR y LIKE deben realizar aproximadamente el mismo.

Cuando el comodín es no un "comodín frontal", el enfoque LIKE debería ser más rápido, a menos que el comodín no sea muy selectivo.

La razón por qué el tipo de comodines y su selectividad cuestión es que un predicado con Instr() se sistemáticamente resultado en un recorrido de tabla (SQL puede no hacer ninguna suposición sobre la semántica de INSTR), mediante el cual SQL puede aproveche su comprensión de la semántica del predicado LIKE para tal vez usar un índice para ayudarlo a probar solo un conjunto reducido de posibles coincidencias.

Como se sugiere en el comentario bajo la pregunta en sí, un índice de texto completo será mucho más rápido. La diferencia depende de la distribución específica de las palabras dentro del texto, y también del tamaño general de la tabla, etc., pero se espera algo del doble de rápido hasta tal vez 10 veces más rápido. Una posible desventaja de usar en el índice de texto completo, además de la sobrecarga general para crear dicho índice, es que a menos que se tenga mucho cuidado al configurar este índice (por ejemplo: definir la lista de palabras de parada, usando una sintaxis de búsqueda específica evitar formas flexionales y similares ...), puede haber casos en los que los resultados proporcionados por FullText no sean los esperados. Por ejemplo, al buscar una "SIERRA" (una herramienta para cortar madera), se pueden obtener muchos éxitos para los registros, incluido el verbo "ver", en sus diversas formas conjugadas.
Por supuesto, estas características de reconocimiento lingüístico de los índices de texto completo generalmente se pueden anular y también se puede considerar que tales características son efectivamente una ventaja, no un inconveniente. Solo menciono esto aquí ya que estamos comparando esto con una búsqueda de comodín simple.

+0

Gracias, muy informativo. – Grekker

3

Hay poco que añadir a la prueba de razzed.Pero, al parecer utilizando regexp no incurrir en una carga de procesamiento mucho más pesado, a diferencia de lo que señala Seth en su comentario.

las siguientes pruebas asumen que se establece query_caching-On en my.ini

query_cache_type = 1 
query_cache_size = 64M 

pruebas

  • Los horarios muestran el rendimiento promedio, de cada tres mediciones (con la memoria caché limpiado de forma intermitente):

  • GUSTO

    SELECT * FROM `domain_model_offers` WHERE `description` LIKE '%inform%' LIMIT 0 , 30 
    

    inicial: 0.0035s
    Cached: 0.0005s

  • REGEXP

    SELECT * FROM `domain_model_offers` WHERE `description` REGEXP 'inform' LIMIT 0 , 30 
    

    inicial: 0,01 s
    Cached: 0,0004

Resultado

LIKE o INSTR es definitivamente más rápido que REGEXP.

aunque mínimo, la diferencia de tiempo de caché es probablemente suficiente para justificar una mayor investigación.

En un sistema configurado MySQL, probablemente, la indexación de texto completo debe ser siempre más rápido en general, o al menos a la par con una búsqueda no indexada. Por lo tanto, utilice la indexación, especialmente en textos largos en lenguaje humano, independientemente del código de marcado intermitente.

9

MySQL - INSTR vs LOCATE vs COMO vs REGEXP

Para mí la INSTR y LOCATE a cabo el más rápido:

# 5.074 sec 
SELECT BENCHMARK(100000000,INSTR('foobar','foo')); 

# 5.086 sec 
SELECT BENCHMARK(100000000,LOCATE('foo','foobar')); 

# 8.990 sec 
SELECT BENCHMARK(100000000,'foobar' LIKE '%foo%'); 

# 14.433 sec 
SELECT BENCHMARK(100000000,'foobar' REGEXP 'foo'); 

# 5.5.35-0ubuntu0.12.10.2 
SELECT @@version; 
+2

¡Repito estas pruebas y veo resultados similares! –

Cuestiones relacionadas