Decir que tengo una relación 1-a-N (person_id, pet_id). Tengo una tabla donde pet_idestá la clave principal.
Entiendo que un índice secundario InnoDB es esencialmente un árbol B donde los valores son los valores de clave primaria correspondientes para la fila.
Ahora, supongamos que una persona puede tener miles de mascotas y, a menudo, quiero las mascotas de una persona en orden pet_id. Entonces sería importante si los registros en el índice secundario se ordenan por (person_id, pet_id)o solo person_idcon los pet_id's para eso person_idsin clasificar. Adivinando lo posterior.
Entonces, si person_idno es único, ¿los registros están ordenados físicamente (person_id, pet_id)o SOLO pet_id?
Gracias
mysql
innodb
primary-key
clustered-index
usuario3391564
fuente
fuente

person_idno es único, ¿los registros están ordenados físicamente(person_id, pet_id)o SOLOperson_id?"Respuestas:
No. Si su tabla tiene el motor InnoDB y
PRIMARY KEYes(pet_id), entonces definir un índice secundario como(person_id)o(person_id, pet_id)no hace ninguna diferencia.El índice también incluye la
pet_idcolumna, por lo que los valores se ordenan como(person_id, pet_id)en ambos casos.Una consulta como la que tienes:
necesitará acceder solo al índice para obtener los valores y aún más, no tendrá que hacer ningún tipo, ya que los
pet_idvalores ya están ordenados en el índice. Puede verificar esto mirando los planes de ejecución (EXPLAIN):Primero, intentamos con una tabla MyISAM:
¡Observe el clasificador de archivos!
Ahora, MyISAM con índice compuesto:
Filesort se ha ido , como se esperaba.
Ahora intentemos lo mismo con el motor InnoDB:
¡No hay clasificación de archivos tampoco! Aunque el índice no tiene explícitamente la
pet_idcolumna, los valores están allí y ordenados. Puede verificar que si define el índice con(person_id, pet_id), elEXPLAINes idéntico.Vamos a hacerlo, con InnoDB y el índice compuesto:
Planes idénticos al caso anterior.
Para estar 100% seguro, también ejecuto los últimos 2 casos (motor InnoDB, con índices únicos y compuestos) que permiten la
file_per_tableconfiguración y agregan algunos miles de filas en la tabla:En ambos casos, al verificar los tamaños de archivo reales, se obtienen resultados idénticos :
fuente
(<some_column>)y(<some_column>, <pk>)porqueON (<some_column>)es equivalente aON (<some_column>) INCLUDE (<pk>)noON (<some_column>, <pk>). En la mayoría de los casos, esto tiene una importancia prácticamente nula, pero si su PK es aleatoria (es decir, un UUID),ON (<s_c>,<pk>)puede generar una fragmentación adicional o si su PK es significativa además de ser una clave y podríaORDER BY s_c, pkser que ese tipo será más rápido como índice Ya está completamente en orden.INCLUDE (columns)embargo, MySQL no tiene funcionalidad. Esa es otra razón por la que concluí que el(s_c)índice es equivalente a(s_c, pk).De acuerdo con la documentación de MySQL sobre los índices agrupados y secundarios
Por lo tanto, agregar la CLAVE PRIMARIA a un índice secundario es definitivamente redundante. Su entrada de índice le gustaría
(person_id, pet_id, pet_id). Esto también hincharía innecesariamente el índice secundario al tener 2 copias dePRIMARY KEY.Para el índice con
(person_id), si tuviera que ejecutar una consulta como estaEl
PRIMARY KEYestaría completamente involucrado en esta consulta y produce los resultados ordenados dePRIMARY KEYtodos modos. Desde un punto de vista físico, las filas están ordenadas por orden de inserción. Si pet_id es AUTO_INCREMENT, entonces se ordena por el número automático.fuente
(owner_id, pet_id)pero puede crear una clave(vet_id, pet_id[, owner_id])para utilizar un orden de columna diferente.Consejo 1:
Es perfectamente válido. Tiene la ventaja de rendimiento de ser más eficiente cuando muchas consultas necesitan encontrar varias filas
WHERE x = 123. Es decir, es un poco más eficiente que lo 'obvio'La única regla sobre
AUTO_INCREMENT(para InnoDB) es queiddebe ser la primera columna de algún índice. Tenga en cuenta que esta regla no dice nada sobrePRIMARYoUNIQUEo 'única columna'.La sugerencia es útil para tablas enormes que a menudo se obtienen
xjunto con otras cosas.Consejo 2: suponga que tiene
Este es un índice de "cobertura":
Es decir, toda la consulta se puede hacer dentro del índice BTree. El EXPLICAR dirá "Usando índice".
fuente