Същественото е, че индексът не може да се използва, ако базата данни трябва да извърши преобразуване от страна на таблицата на сравнението.
Освен това DB винаги прикрива Strings -> Numbers, защото това е детерминистичният начин (в противен случай 1 може да се преобразува в '01', '001', както е споменато в коментарите).
Така че, ако сравним двата случая, които изглежда ви объркват:
-- index is used
EXPLAIN SELECT * FROM a_table WHERE int_column = '1';
DB преобразува низа '1' в числото 1 и след това изпълнява заявката. Най-накрая има int от двете страни, за да може да използва индекса.
-- index is NOT used. WTF?
EXPLAIN SELECT * FROM a_table WHERE str_column = 1;
Отново преобразува низа в числа. Този път обаче трябва да преобразува данните, съхранени в таблицата. Всъщност вие извършвате търсене като cast(str_column as int) = 1
. Това означава, че вече не търсите в индексираните данни, DB не може използвайте индекса.
Моля, разгледайте това за повече подробности:
- 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