2009-04-16 23 views
8

he añadido un índice FULLTEXT a una de mis tablas de bases de datos MySQL de la siguiente manera:¿Por qué la cardinalidad de un índice en MySQL permanece sin cambios cuando agrego un nuevo índice?

ALTER TABLE members ADD FULLTEXT(about,fname,lname,job_title); 

El problema es que el uso de phpMyAdmin puedo ver la cardinalidad de mi nuevo índice sólo es . ¿Esto significa que el índice nunca se usará?

He ejecutado un comando de tabla de análisis pero no pareció hacer nada.

analyze table members 

Los tipos respectivos de los campos de índice son varchar (100), varchar (100), texto, varchar (200) y el motor utilizado es MyISAM y la tabla tiene alrededor de 30.000 filas, todos únicos. Mi versión de MySQL es 5.0.45.

¿Estoy haciendo algo mal?

Respuesta

13

Si solo tiene 1 fila en la tabla, la cardinalidad para el índice debería ser 1, por supuesto. Solo está contando el número de valores únicos.

Si piensa en un índice como una tabla de búsqueda basada en segmentos (como un hash), entonces la cardinalidad es el número de segmentos.

Así es como funciona: Cuando construye un índice sobre un conjunto de columnas (a,b,c,d), la base de datos pasa por todas las filas de la tabla, mirando los cuatrillizos ordenados de esas 4 columnas, para cada fila. Digamos que su mesa se ve así:

a b c d e 
-- -- -- -- -- 
1 1 1 1 200 
1 1 1 1 300 
1 2 1 1 200 
1 3 1 1 200 

Entonces, ¿qué se ve la base de datos en el se encuentra a las 4 columnas (a, b, c, d):

a b c d 
-- -- -- -- 
1 1 1 1 
1 2 1 1 
1 3 1 1 

ver que hay solamente 3 único filas restantes? Esos se convertirán en nuestros cubos, pero volveremos sobre eso. En realidad, también hay una identificación de registro o identificador de fila para cada fila en la tabla. Por lo que nuestra tabla original se ve así:

(row id) a b c d e 
-------- -- -- -- -- -- 
00000001 1 1 1 1 200 
00000002 1 1 1 1 300 
00000003 1 2 1 1 200 
00000004 1 3 1 1 200 

Así que cuando miramos sólo las 4 columnas de (a, b, c, d), Realmente estamos también en la fila Identificación:

(row id) a b c d 
-------- -- -- -- -- 
00000001 1 1 1 1 
00000002 1 1 1 1 
00000003 1 2 1 1 
00000004 1 3 1 1 

Pero lo que queremos hacer operaciones de búsqueda por (a, b, c, d) y no por la fila de identificación, por lo que producen algo como esto:

(a,b,c,d) (row id) 
--------- -------- 
1,1,1,1 00000001 
1,1,1,1 00000002 
1,2,1,1 00000003 
1,3,1,1 00000004 

y por último, los identificadores de grupo de toda la fila de filas que tienen valores de identicle (a, b, c, d) juntos:

(a,b,c,d) (row id) 
--------- --------------------- 
1,1,1,1 00000001 and 00000002 
1,2,1,1 00000003 
1,3,1,1 00000004 

¿Ver eso? Los valores de (a, b, c, d), que son (1,1,1,1) (1,2,1,1) y (1,3,1,1) se han convertido en claves para nuestra tabla de búsqueda en las filas de la tabla original.

En realidad, nada de esto realmente sucede, pero debería darle una buena idea sobre cómo se podría hacer una implementación "ingenua" (es decir, directa) de un índice.

Pero la conclusión es esta: la cardinalidad solo mide cuántas filas únicas hay en un índice. Y en nuestro ejemplo, esa era la cantidad de claves en nuestra tabla de búsqueda, que era 3.

Espero que ayude!

+0

Gracias por la información del índice. Muy bien explicado. La cardinalidad de mi índice debería ser más de 1 dado que hay 30000 filas y casi cada miembro tiene un nombre diferente. – Tom

+0

Gracias por la explicación sobre los índices, fue muy bueno, pero su explicación no respondió la pregunta anterior. –

+0

Tiene razón, no dije explícitamente la conclusión final: acabo de mostrar que 4 filas se dividen en 3 segmentos. Estoy seguro de que podría inventar otra fila que podría agregarse que caería en uno de los 3 segmentos existentes del índice. Eso dejaría sin cambios el número de segmentos, lo que también significaría que la cardinalidad del índice no se modificó. Lo siento por eso. – scraimer

8

No puedo responder definitivamente por qué MySQL no calcula la cardinalidad, pero puedo adivinar. El MySQL manual estados:

Cardinalidad: una estimación del número de valores únicos en el índice. Esto se actualiza ejecutando ANALYZE TABLE o myisamchk -a. La cardinalidad se cuenta en función de estadísticas almacenadas como enteros, por lo que el valor no es necesariamente exacto ni siquiera para tablas pequeñas. Cuanto mayor es la cardinalidad, mayor es la posibilidad de que MySQL use el índice cuando realiza uniones.

Los índices FULLTEXT solo se utilizan en las consultas MATCH ... EN CONTRA (...), lo que obliga a utilizar el índice. La sintaxis MATCH ... ANTES no funciona si no hay un índice FULLTEXT en esos campos.

Supongo que la cardinalidad no se calcula porque realmente no es necesario.

Tenga en cuenta que las búsquedas en el índice funcionan aunque la cardinalidad no esté establecida.

Para el registro, una declaración de foobar ANALYZE TABLE parece establecer la cardinalidad correctamente.

Cuestiones relacionadas