2011-09-21 15 views
20

¿Alguien sabe cuál es más rápido:MySQL COMO vs LOCALIZAR

SELECT * FROM table WHERE column LIKE '%text%'; 

o

SELECT * FROM table WHERE LOCATE('text',column)>0; 
+0

¿Por qué no comparar/hacer un perfil de esto y descubrirlo? – marto

+0

@matro: qué es benchmark/profile .just for enthu – Gowri

+3

Me gusta debería ser más rápido. Un índice de texto completo y 'match against' será mucho más rápido. – Johan

Respuesta

21

Agregado 20a de abril de, 2015: Por favor, lea también Hallie's answer continuación


Primero uno pero marginalmente Principalmente porque no tiene que hacer una comparación extra de > 0.

mysql> SELECT BENCHMARK(100000000,LOCATE('foo','foobar')); 
+---------------------------------------------+ 
| BENCHMARK(100000000,LOCATE('foo','foobar')) | 
+---------------------------------------------+ 
|           0 | 
+---------------------------------------------+ 
1 row in set (3.24 sec) 

mysql> SELECT BENCHMARK(100000000,LOCATE('foo','foobar') > 0); 
+-------------------------------------------------+ 
| BENCHMARK(100000000,LOCATE('foo','foobar') > 0) | 
+-------------------------------------------------+ 
|            0 | 
+-------------------------------------------------+ 
1 row in set (4.63 sec) 


mysql> SELECT BENCHMARK(100000000,'foobar' LIKE '%foo%'); 
+--------------------------------------------+ 
| BENCHMARK(100000000,'foobar' LIKE '%foo%') | 
+--------------------------------------------+ 
|           0 | 
+--------------------------------------------+ 
1 row in set (4.28 sec) 


mysql> SELECT @@version; 
+----------------------+ 
| @@version   | 
+----------------------+ 
| 5.1.36-community-log | 
+----------------------+ 
1 row in set (0.01 sec) 
+0

¿Cómo funciona 'benchmark'? ¿Cuál es la precisión de estos números? – Pacerier

+0

'BENCHAMRK' simplemente ejecuta la expresión proporcionada un número determinado de veces. https://dev.mysql.com/doc/refman/5.5/en/select-benchmarking.html En cuanto a la precisión, no puedo decir mucho. Sin embargo, creo que es bastante bueno en cuanto a la precisión. – Mchl

4

Hice algunas pruebas como Mchi hizo. Y creo que es difícil decir cuál es más rápido. Parece que depende de la primera aparición de la subcadena.

mysql> select benchmark(100000000, 'afoobar' like '%foo%'); 
+----------------------------------------------+ 
| benchmark(100000000, 'afoobar' like '%foo%') | 
+----------------------------------------------+ 
|           0 | 
+----------------------------------------------+ 
1 row in set (9.80 sec) 

mysql> select benchmark(100000000, locate('foo', 'afoobar')); 
+------------------------------------------------+ 
| benchmark(100000000, locate('foo', 'afoobar')) | 
+------------------------------------------------+ 
|            0 | 
+------------------------------------------------+ 
1 row in set (8.08 sec) 

mysql> select benchmark(100000000, 'abfoobar' like '%foo%'); 
+-----------------------------------------------+ 
| benchmark(100000000, 'abfoobar' like '%foo%') | 
+-----------------------------------------------+ 
|            0 | 
+-----------------------------------------------+ 
1 row in set (10.55 sec) 

mysql> select benchmark(100000000, locate('foo', 'abfoobar')); 
+-------------------------------------------------+ 
| benchmark(100000000, locate('foo', 'abfoobar')) | 
+-------------------------------------------------+ 
|            0 | 
+-------------------------------------------------+ 
1 row in set (10.63 sec) 

mysql> select benchmark(100000000, 'abcfoobar' like '%foo%'); 
+------------------------------------------------+ 
| benchmark(100000000, 'abcfoobar' like '%foo%') | 
+------------------------------------------------+ 
|            0 | 
+------------------------------------------------+ 
1 row in set (11.54 sec) 

mysql> select benchmark(100000000, locate('foo', 'abcfoobar')); 
+--------------------------------------------------+ 
| benchmark(100000000, locate('foo', 'abcfoobar')) | 
+--------------------------------------------------+ 
|            0 | 
+--------------------------------------------------+ 
1 row in set (12.48 sec) 

mysql> select @@version; 
+------------+ 
| @@version | 
+------------+ 
| 5.5.27-log | 
+------------+ 
1 row in set (0.01 sec) 
+0

¡Buena captura! ¡No he pensado en probar eso! – Mchl

5

+1 a @Mchl por responder la pregunta más directamente.

Pero debemos tener en cuenta que ninguna de las soluciones puede usar un índice, por lo que están obligados a hacer escaneos de tabla.

Tratar de decidir entre un paño o un vendaje adhesivo de plástico es una tontería, cuando está tratando de parchear el casco del Titanic.

Para este tipo de consulta, se necesita un full-text search index. Dependiendo del tamaño de la tabla, esto será hundreds or thousands of times faster.

+2

El problema con el texto completo en MySQL es que actualmente no es capaz de buscar comodines, solo búsqueda de prefijos ('foo *' coincidirá con 'foobar', pero' * bar' no). – Itai

+1

Apache Lucene y Solr tienen la misma limitación. Sphinx Search es compatible con la indexación infija, por lo que puede poner comodines al comienzo de un patrón. Ver http://sphinxsearch.com/docs/current/conf-min-infix-len.html –