Mysql
 sql >> Base de données >  >> RDS >> Mysql

MySQL EXPLAIN 'type' passe de 'range' à 'ref' lorsque la date dans l'instruction where est modifiée ?

Différentes stratégies de recherche ont un sens pour différentes données. En particulier, les parcours d'index (tels que la plage) doivent souvent effectuer une recherche pour lire réellement la ligne. À un moment donné, effectuer toutes ces recherches est plus lent que de ne pas utiliser l'index du tout.

Prenons un exemple trivial, une table à trois colonnes :id (clé primaire), nom (indexé), anniversaire. Disons qu'il contient beaucoup de données. Si vous demandez à MySQL de rechercher l'anniversaire de Bob, il peut le faire assez rapidement :d'abord, il trouve Bob dans l'index des noms (cela prend quelques recherches, log(n) où n est le nombre de lignes), puis une recherche supplémentaire pour lire la ligne réelle dans le fichier de données et en lire l'anniversaire. C'est très rapide, et bien plus rapide que de parcourir l'intégralité du tableau.

Ensuite, pensez à faire un name like 'Z%' . C'est probablement une partie assez petite du tableau. Il est donc encore plus rapide de trouver où les Z commencent dans l'index des noms, puis pour chacun, recherchez le fichier de données pour lire la ligne. (Il s'agit d'un balayage de distance).

Enfin, envisagez de demander tous les noms commençant par M-Z. C'est probablement environ la moitié des données. Il pourrait faire un balayage de gamme, puis un beaucoup de recherches, mais rechercher de manière aléatoire sur le fichier de données dans le but ultime de lire la moitié des lignes n'est pas optimal :il serait plus rapide de simplement effectuer une grande lecture séquentielle sur le fichier de données. Donc, dans ce cas, l'index sera ignoré.

C'est ce que vous voyez - sauf dans votre cas, il y a une autre clé sur laquelle il peut se rabattre. (Il est également possible qu'il utilise l'index de date s'il n'avait pas l'autre, il devrait choisir l'index qui sera le plus rapide. Attention, l'optimiseur de MySQL fait souvent des erreurs à cet égard.)

Bref, c'est prévu. Une requête ne dit pas comment pour récupérer les données, il dit plutôt quoi données à récupérer. L'optimiseur de la base de données est censé trouver le moyen le plus rapide de la récupérer.

Vous pouvez trouver un index sur les deux colonnes, dans l'ordre (public_key,created_on_date) est préféré dans les deux cas, et accélère votre requête. En effet, MySQL ne peut utiliser qu'un seul index par table (par requête). De plus, la date va à la fin car un balayage de plage ne peut être effectué efficacement que sur la dernière colonne d'un index.

[InnoDB a en fait une autre couche d'indirection, je crois, mais cela ne ferait que confondre le point. Cela ne change rien à l'explication.]