2010-02-28 11 views
65

Me enfrento a lo siguiente y no estoy seguro de cuál es la mejor práctica.¿Dos índices de una sola columna frente a un índice de dos columnas en MySQL?

Tenga en cuenta la siguiente tabla (que conseguirá grande):

Identificación del PK | giver_id FK | recipient_id FK | fecha

Estoy usando InnoDB y por lo que entiendo, crea índices automáticamente para las dos columnas de clave externa. Sin embargo, también estaré haciendo muchas consultas donde necesito hacer coincidir una combinación particular de:

SELECT...WHERE giver_id = x AND recipient_id = t.

Cada combinación es única en la tabla.

¿Hay alguna ventaja de agregar un índice de dos columnas sobre estas columnas, o los dos índices individuales en teoría serían suficientes/lo mismo?

Respuesta

76

Si tiene dos índices de una sola columna, solo se usará uno de ellos en su ejemplo.

Si tiene un índice con dos columnas, la consulta puede ser más rápida (debe medir). Un índice de dos columnas también se puede usar como índice de una sola columna, pero solo para la columna que figura primero.

A veces puede ser útil tener un índice en (A, B) y otro índice en (B). Esto hace que las consultas utilizando una o ambas columnas sean rápidas, pero por supuesto también usa más espacio en el disco.

Al elegir los índices, también debe tener en cuenta el efecto de insertar, eliminar y actualizar. Más índices = actualizaciones más lentas.

21

Un índice de cobertura como:

ALTER TABLE your_table ADD INDEX (giver_id, recipient_id); 

... significaría que el índice podría ser utilizado si una consulta se refiere a giver_id, o una combinación de giver_id y recipient_id. Tenga en cuenta que los criterios de índice se basan más a la izquierda: una consulta que se refiera solo a recipient_id no podrá usar el índice de cobertura en la declaración que proporcioné.

Además, MySQL solo puede usar un índice por SELECCIÓN, por lo que un índice de cobertura sería la mejor manera de optimizar sus consultas.

+4

'MySQL solo puede usar un índice por SELECCIONAR' esto ya no es cierto, sería bueno si editó su respuesta para actualizarse. – Davor

+0

¿Le importaría explicar por qué el índice de cobertura no podría ser utilizado por 'recipient_id'? –

+2

@IvoPereira Los índices de columnas múltiples en MySQL le permiten usar todos los campos en el índice de izquierda a derecha. Por ejemplo, si tiene un 'INDEX (col1, col2, col3, col4)', entonces el índice se aplicará para búsquedas con una cláusula 'WHERE' como' col1 = 'A'' o 'col1 =' A 'AND col2 = 'B'' o' col1 = 'A' AND col2 = 'B' AND col3 = 'C' AND col4 = 'D'', pero este índice en particular no se usará para nada como 'WHERE col2 = 'B' 'o' WHERE col3 = 'C' AND col4 = 'D'' porque los campos de búsqueda no se dejan más en la definición del índice. Debería agregar índices adicionales para cubrir esos campos. – Slicktrick

3

Si uno de los índices de clave externa ya es muy selectivo, el motor de la base de datos debe usar ese para la consulta que especificó. La mayoría de los motores de base de datos utilizan algún tipo de heurística para poder elegir el índice óptimo en esa situación. Si ninguno de los índices es altamente selectivo por sí mismo, probablemente tiene sentido agregar el índice creado en ambas teclas, ya que dice que usará mucho ese tipo de consulta.

Otra cosa a considerar es si puede eliminar el campo PK en esta tabla y definir el índice de clave primaria en los campos giver_id y recipient_id. Dijiste que la combinación es única, así que posiblemente funcionaría (dadas muchas otras condiciones que solo tú puedes responder). Normalmente, sin embargo, creo que la complejidad añadida que se agrega no vale la pena.

+0

Gracias Mark, una de las claves es de hecho muy selectiva, así que debería estar bien. Opté por mantener los dos índices (automáticos) en su lugar y ver cómo funciona en el tiempo. También pensé en un dador combinado: la clave primaria del destinatario, pero como cada campo también debe poder buscarse individualmente, simplemente agregaría la sobrecarga de php. Además, la nueva clave sería una cadena (más larga) en lugar de un entero (más corto). – Tom

0

Otra cosa a considerar es que las características de rendimiento de ambos enfoques se basarán en el tamaño y la cardinalidad del conjunto de datos. Puede encontrar que el índice de 2 columnas solo se da cuenta de un rendimiento mayor en un cierto umbral de tamaño de conjunto de datos, o exactamente lo contrario.Nada puede sustituir las métricas de rendimiento para su escenario exacto.

Cuestiones relacionadas