Me enfrento a lo siguiente y no estoy seguro de cuál es la mejor práctica.
Considere la siguiente tabla (que se agrandará):
id PK | giver_id FK | destinatario_id FK | fecha
Estoy usando InnoDB y, por lo que tengo entendido, crea índices automáticamente para las dos columnas de clave externa. Sin embargo, también haré muchas consultas en las que necesito hacer coincidir una combinación particular de:
SELECT...WHERE giver_id = x AND recipient_id = t
.
Cada una de estas combinaciones será única en la tabla.
¿Existe algún beneficio al agregar un índice de dos columnas sobre estas columnas, o los dos índices individuales en teoría serían suficientes / iguales?
Respuestas:
Si tiene dos índices de una sola columna, solo uno de ellos se usará 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 utilizar como índice de una sola columna, pero solo para la columna que se enumera primero.
A veces puede resultar útil tener un índice en (A, B) y otro en (B). Esto agiliza las consultas que utilizan una o ambas columnas, pero, por supuesto, también utiliza más espacio en 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.
fuente
Un índice de cobertura como:
... significaría que el índice podría usarse si se hace referencia a una consulta
giver_id
, o una combinación degiver_id
yrecipient_id
. Tenga en cuenta que los criterios de índice se basan en el extremo izquierdo: una consulta que se refiera solorecipient_id
no podría usar el índice de cobertura en la declaración que proporcioné.Además, MySQL solo puede usar un índice por SELECT, por lo que un índice de cobertura sería el mejor medio para optimizar sus consultas.
fuente
MySQL can only use one index per SELECT
esto ya no es cierto, sería bueno si editara su respuesta para actualizarla.recipient_id
?INDEX (col1, col2, col3, col4)
, el índice se aplicará a las búsquedas con unaWHERE
cláusula comocol1 = 'A'
ocol1 = 'A' AND col2 = 'B'
ocol1 = 'A' AND col2 ='B' AND col3 = 'C' AND col4 = 'D'
, pero este índice en particular no se usará para nada comoWHERE col2 = 'B'
oWHERE col3 = 'C' AND col4 = 'D'
porque los campos de búsqueda no se dejan en la mayoría de la definición del índice. Tendría que agregar índices adicionales para cubrir esos campos.Si uno de los índices de clave externa ya es muy selectivo, entonces el motor de la base de datos debería 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 muy selectivo por sí mismo, probablemente tenga sentido agregar el índice creado en ambas claves, 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
yrecipient_id
. Dijo que la combinación es única, por lo que posiblemente funcionaría (dadas muchas otras condiciones que solo usted puede responder). Sin embargo, por lo general, creo que la complejidad adicional que agrega no vale la pena.fuente
Otra cosa a considerar es que las características de desempeño de ambos enfoques se basarán en el tamaño y cardinalidad del conjunto de datos. Puede encontrar que el índice de 2 columnas solo se vuelve más eficaz en un determinado umbral de tamaño del conjunto de datos, o exactamente lo contrario. Nada puede sustituir las métricas de rendimiento para su escenario exacto.
fuente