2012-04-27 8 views
11

Tener esta tabla:Optimización de consultas MySQL COMO '% cadena%' en InnoDB

CREATE TABLE `example` (
`id` int(11) unsigned NOT NULL auto_increment, 
`keywords` varchar(200) NOT NULL, 
PRIMARY KEY (`id`) 
) ENGINE=InnoDB; 

Nos gustaría optimizar la siguiente consulta:

SELECT id FROM example WHERE keywords LIKE '%whatever%' 

La mesa es InnoDB, (por lo que no FULLTEXT por ahora) ¿cuál sería el mejor índice para usar para optimizar tal consulta?

Hemos tratado de un simple:

ALTER TABLE `example` ADD INDEX `idxSearch` (`keywords`); 

Pero un explican consulta muestra que necesidad de escanear toda la tabla si nuestras consultas en las LIKE '% lo' en lugar, este índice se realiza bien, pero de lo contrario no tiene valor.

¿Hay alguna forma de optimizar esto para innoDB?

Gracias!

+0

Recomiendo también algún ajuste de rendimiento de mysql, [mysqltuner.pl] (http://mysqltuner.com/) o [tuning-primer.sh] (http://www.day32.com/MySQL/) – jaggedsoft

Respuesta

38

Los índices se crean desde el inicio de la cadena hacia el final. Cuando utiliza la cláusula de tipo LIKE 'whatever%', MySQL puede usar esos índices basados ​​en el inicio para buscar whatever muy rápidamente.

Pero cambiar a LIKE '%whatever%' elimina ese anclaje al inicio de la cadena. Ahora, los índices basados ​​en el inicio no se pueden usar, porque el término de búsqueda ya no está anclado al comienzo de la cadena; está "flotando" en algún lugar en el medio y todo el campo debe buscarse. Cualquier consulta LIKE '%... nunca puede usar índices.

Es por eso que utilizas índices de texto completo si todo lo que estás haciendo son búsquedas 'flotantes', porque están diseñadas para ese tipo de uso.

Nota importante: InnoDB ahora supports fulltext índices a partir de la versión 5.6.4. Entonces, a menos que no pueda actualizar al menos a 5.6.4, no hay nada que le impida usar InnoDB * Y búsquedas de texto completo.

+0

+1 para una gran explicación –

+0

Gracias, pues estoy usando MySQL 5.0.77-log en un entorno de nube así que no hay manera de actualizar :( Consideraré mover la tabla a MyIsam luego – jmserra

+0

Si nos mudamos a InnoDB tendríamos que cambiar las consultas para usar MATCH/AGAINST? o el uso actual del beneficio 'LIKE' del índice FullText? Gracias de nuevo – jmserra

0

Me gustaría comentar que sorprendentemente, la creación de un índice también ayudó a acelerar las consultas para las consultas like '%abc%' en mi caso.

Corriendo MySQL 5.5.50 en Ubuntu (dejando todo en el valor predeterminado), he creado una tabla con muchas columnas y he insertado 100,000 entradas ficticias. En una columna, inserté cadenas completamente aleatorias con 32 caracteres (es decir, todas son únicas).

Realicé algunas consultas y luego agregué un índice en esta columna. Un simple

select id, searchcolumn from table_x where searchcolumn like '%ABC%' 

devuelve un resultado en ~2 secondssin el índice y en 0.05 secondscon el índice.

Esto no se ajusta a las explicaciones anteriores (y en muchos otros mensajes). Cuál podría ser la razón para eso?

EDIT He comprobado la salida de EXPLAIN.La salida dice filas es 100,000, pero la información adicional es "Using where; Using index". Entonces, de alguna manera, ¿el DBMS tiene que buscar todas las filas, pero todavía puede utilizar el índice?

+0

Tu consulta no contiene una condición LIKE. Es por eso que se está usando el índice. – ditscheri

+0

@ditscheri Disculpa, esto fue un error tipográfico, en realidad es una condición LIKE (acaba de corregir mi posición t) – abulhol

Cuestiones relacionadas