Un colega me pidió que explicara cómo los índices (índices) aumentan el rendimiento; Intenté hacerlo, pero me confundí.
Utilicé el modelo a continuación para la explicación (una base de datos de registro de errores/diagnósticos). Se compone de tres tablas:¿Se requiere un índice compuesto para acelerar la consulta combinada?
- Lista de los sistemas de negocio, mesa de "sistema" que contiene sus nombres
- Lista de diferentes tipos de huellas, "TraceTypes" mesa, definiendo qué tipos de mensajes de error puede estar conectado a
- mensajes de seguimiento actuales, que tienen las claves externas de
System
yTraceTypes
tablas
he usado MySQL para la demo, sin embargo, no recuerdo los tipos de tabla que utilicé. Creo que fue InnoDB.
System TraceTypes
----------------------------- ------------------------------------------
| ID | Name | | ID | Code | Description |
----------------------------- ------------------------------------------
| 1 | billing | | 1 | Info | Informational mesage |
| 2 | hr | | 2 | Warning| Warning only |
----------------------------- | 3 | Error | Failure |
| ------------------------------------------
| ------------|
Traces | |
--------------------------------------------------
| ID | System_ID | TraceTypes_ID | Message |
--------------------------------------------------
| 1 | 1 | 1 | Job starting |
| 2 | 1 | 3 | System.nullr..|
--------------------------------------------------
En primer lugar, he añadido algunos registros a todas las tablas y demostró que la consulta a continuación se ejecuta en 0.005 segundos:
select count(*) from Traces
inner join System on Traces.System_ID = System.ID
inner join TraceTypes on Traces.TraceTypes_ID = TraceTypes.ID
where
System.Name='billing' and TraceTypes.Code = 'Info'
Entonces me genera más datos (no hay índices aún)
- "Sistema" contenía aproximadamente 100 entradas
- "Tipo de traza" contenía aproximadamente 50 entradas
- "Huellas" contenía ~ 10 millones de registros.
Ahora la consulta anterior tomó 8-10 segundos.
Creé índices en la columna Traces.System_ID
y en la columna Traces.TraceTypes_ID
. Ahora esta consulta ejecutada en milisegundos:
select count(*) from Traces where System_id=1 and TraceTypes_ID=1;
Esto también fue rápido:
select count(*) from Traces
inner join System on Traces.System_ID = System.ID
where System.Name='billing' and TraceTypes_ID=1;
pero la consulta anterior, que se unió a las tres mesas todavía tardó 8-10 segundos en completarse.
Solo cuando creé un índice compuesto (columnas System_ID y TraceTypes_ID incluidas en el índice), la velocidad disminuyó a milisegundos.
La afirmación básica que me enseñaron antes es "todas las columnas que usa para unir, debe estar indexada".
Sin embargo, en mi escenario tenía índices tanto en System_ID
y TraceTypes_ID
, sin embargo, MySQL no los usó. La pregunta es, ¿por qué? Mis apuestas son: la relación de recuento de elementos 100: 10,000,000: 50 hace que los índices de una sola columna sean demasiado grandes para ser utilizados. ¿Pero es verdad?
tahnk usted, nunca supe de tal "regla de un índice por tabla", pero parece ser lógico y también - para explicar mi problema (yo estaba en mysql5.4.algo, sin embargo). – naivists