sql >> Base de Datos >  >> RDS >> Mysql

Índices compuestos y de texto completo y cómo afectan a la consulta

Si entiendo su pregunta, sabe que MATCH AGAINST usa su índice FULLTEXT y se pregunta cómo aplica MySQL el resto de la cláusula WHERE (es decir, ¿hace un escaneo de tablas o una búsqueda indexada).

Esto es lo que asumo sobre su tabla:tiene una CLAVE PRIMARIA en alguna columna de identificación y el índice FULLTEXT.

En primer lugar, MySQL nunca use el índice FULLTEXT para la cláusula WHERE de ciudad/estado. ¿Por qué? Porque los índices FULLTEXT solo se aplican con COINCIDIR CONTRA. Ver aquí en el párrafo después del primer conjunto de viñetas (no las viñetas de la tabla de contenido).

EDITAR: En su caso, asumiendo que su tabla no solo tiene como 10 filas, MySQL aplicará el índice de TEXTO COMPLETO para su PARTIDO EN CONTRA, luego hará un escaneo de tablas en esos resultados para aplicar la ciudad/estado DONDE.

Entonces, ¿qué sucede si agrega un índice BTREE a la ciudad y el estado?

CREATE INDEX city__state ON table (city(10),state(2)) USING BTREE;

Bueno, MySQL solo puede usar uno index para esta consulta ya que es una simple selección. Será cualquiera use el TEXTO COMPLETO o el BTREE. Tenga en cuenta que cuando digo un índice, me refiero a una definición de índice, no a una columna en un índice de varias partes. De todos modos, esto plantea la pregunta de cuál hace que usa?

Eso depende del análisis de la tabla. MySQL intentará estimar (basado en las estadísticas de la tabla de la última OPTIMIZE TABLE) qué índice eliminará la mayoría de los registros. Si la ciudad/estado DONDE lo reduce a 10 registros mientras que COINCIDIR EN CONTRA solo lo reduce a 100, entonces MySQL usará el índice de ciudad__estado primero para la ciudad/estado DÓNDE y luego haga un escaneo de tablas para el PARTIDO EN CONTRA.

Por otro lado, si MATCH_AGAINST lo reduce a 10 registros mientras que la ciudad/estado DONDE lo reduce a solo 1000, entonces MySQL aplicará el índice FULLTEXT primero y escaneará las tablas para la ciudad y el estado.

El resultado final es la cardinalidad de su índice. Esencialmente, ¿qué tan únicos son los valores que entrarán en su índice? Si cada registro en su tabla tiene la ciudad establecida en Oakland, entonces no es una clave muy única y, por lo tanto, tiene city ='Oakland' realmente no reduce tanto la cantidad de registros para usted. En ese caso, decimos que su índice de ciudad__estado tiene una baja cardinalidad .

En consecuencia, si el 90% de las palabras en su índice FULLTEXT son "John", eso tampoco le ayuda mucho por las mismas razones.

Si puede permitirse el espacio y la sobrecarga de ACTUALIZAR/ELIMINAR/INSERTAR, recomendaría agregar el índice BTREE y dejar que MySQL decida qué índice quiere usar. En mi experiencia, por lo general hace un muy buen trabajo al elegir el correcto.

Espero haber respondido a tu pregunta.

EDITAR: En una nota al margen, asegúrese de elegir el tamaño correcto para su índice BTREE (en mi ejemplo, elegí los primeros 10 caracteres en la ciudad). Obviamente, esto tiene un gran impacto en la cardinalidad. Si eligió la ciudad (1), obviamente obtendrá una cardinalidad más baja que si eligió la ciudad (10).

EDIT2: El plan de consulta de MySQL (estimación) para el cual el índice elimina la mayor cantidad de registros es lo que ve en EXPLAIN.