Le point essentiel est que l'index ne peut pas être utilisé si la base de données doit faire une conversion côté table de la comparaison.
En plus de cela, la base de données couvre toujours Strings -> Numbers car c'est la méthode déterministe (sinon 1 pourrait être converti en '01', '001' comme mentionné dans les commentaires).
Alors, si on compare les deux cas qui semblent vous dérouter :
-- index is used
EXPLAIN SELECT * FROM a_table WHERE int_column = '1';
La base de données convertit la chaîne '1' en nombre 1, puis exécute la requête. Il a enfin int des deux côtés pour pouvoir utiliser l'index.
-- index is NOT used. WTF?
EXPLAIN SELECT * FROM a_table WHERE str_column = 1;
Encore une fois, il convertit la chaîne en nombres. Cependant, cette fois, il doit convertir les données stockées dans la table. En fait, vous effectuez une recherche du type cast(str_column as int) = 1
. Cela signifie que vous ne cherchez plus sur les données indexées, la base de données ne peut pas utilisez l'index.
Veuillez consulter ceci pour plus de détails :
- http://use-the- index-luke.com/sql/where-clause/obfuscation/numeric-strings
- http://use- the-index-luke.com/sql/where-clause/functions/case-insensible-search