Det væsentlige er, at indekset ikke kan bruges, hvis databasen skal lave en konvertering på tabelsiden af sammenligningen.
Udover det, skjuler DB'en altid Strings -> Tal, fordi dette er den deterministiske måde (ellers kunne 1 konverteres til '01', '001' som nævnt i kommentarerne).
Så hvis vi sammenligner de to tilfælde, der ser ud til at forvirre dig:
-- index is used
EXPLAIN SELECT * FROM a_table WHERE int_column = '1';
DB'en konverterer strengen '1' til tallet 1 og udfører derefter forespørgslen. Den har endelig int på begge sider, så den kan bruge indekset.
-- index is NOT used. WTF?
EXPLAIN SELECT * FROM a_table WHERE str_column = 1;
Igen konverterer den strengen til tal. Denne gang skal den dog konvertere de data, der er gemt i tabellen. Faktisk udfører du en søgning som cast(str_column as int) = 1
. Det betyder, at du ikke søger på de indekserede data længere, databasen kan ikke brug indekset.
Tag et kig på dette for yderligere detaljer:
- http://use-the- index-luke.com/sql/where-clause/obfuscation/numeric-strings
- http://use- the-index-luke.com/sql/where-clause/functions/case-insensitive-search