sql >> Base de Datos >  >> RDS >> Mysql

MySQL EXPLAIN 'tipo' cambia de 'rango' a 'ref' cuando se cambia la fecha en la instrucción where?

Diferentes estrategias de búsqueda tienen sentido para diferentes datos. En particular, los escaneos de índice (como el rango) a menudo tienen que hacer una búsqueda para leer la fila. En algún momento, hacer todas esas búsquedas es más lento que no usar el índice en absoluto.

Tome un ejemplo trivial, una tabla con tres columnas:id (clave principal), nombre (indexado), cumpleaños. Digamos que tiene muchos datos. Si le pide a MySQL que busque el cumpleaños de Bob, puede hacerlo bastante rápido:primero, encuentra a Bob en el índice de nombres (esto requiere algunas búsquedas, log(n) donde n es el número de filas), luego una búsqueda adicional para lea la fila real en el archivo de datos y lea el cumpleaños de ella. Eso es muy rápido y mucho más rápido que escanear toda la tabla.

A continuación, considere hacer un name like 'Z%' . Esa es probablemente una porción bastante pequeña de la mesa. Entonces, es aún más rápido encontrar dónde comienzan las Z en el índice de nombres, luego, para cada uno, busque el archivo de datos para leer la fila. (Este es un escaneo de rango).

Finalmente, considere pedir todos los nombres que comiencen con M-Z. Eso es probablemente alrededor de la mitad de los datos. Podría hacer un escaneo de rango, y luego mucho de búsquedas, pero buscar aleatoriamente en el archivo de datos con el objetivo final de leer la mitad de las filas no es óptimo:sería más rápido simplemente hacer una gran lectura secuencial en el archivo de datos. Entonces, en este caso, el índice será ignorado.

Esto es lo que está viendo, excepto que en su caso, hay otra clave a la que puede recurrir. (También es posible que en realidad use el índice de fecha si no tuviera el otro, debería elegir el índice que sea más rápido. Tenga en cuenta que el optimizador de MySQL a menudo comete errores en esto).

Entonces, en resumen, esto es lo esperado. Una consulta no dice cómo para recuperar los datos, más bien dice qué datos a recuperar. Se supone que el optimizador de la base de datos debe encontrar la forma más rápida de recuperarla.

Puede encontrar un índice en ambos columnas, en el orden (public_key,created_on_date) es preferible en ambos casos y acelera su consulta. Esto se debe a que MySQL solo puede usar un índice por tabla (por consulta). Además, la fecha va al final porque un escaneo de rango solo se puede realizar de manera eficiente en la última columna de un índice.

[InnoDB en realidad tiene otra capa de direccionamiento indirecto, creo, pero solo confundiría el punto. No hace ninguna diferencia en la explicación.]