Bug #32308 comparing varchar column with int constant not using index
Submitted: 13 Nov 2007 10:10 Modified: 13 Nov 2007 10:48
Reporter: Sergey Vladimirov Email Updates:
Status: Not a Bug Impact on me:
None 
Category:MySQL Server: Optimizer Severity:S5 (Performance)
Version:5.0.33-log OS:Linux (SunOS *.*.* 5.11 snv_75 i86pc i386 i86pc)
Assigned to: CPU Architecture:Any

[13 Nov 2007 10:10] Sergey Vladimirov
Description:
plan is not optimal when comparing varchar column and int constant is used:

Non-optimal plan:
mysql> explain SELECT id FROM objects_resources WHERE url=123202;
+----+-------------+-------------------+------+---------------+------+---------+------+-------+-------------+
| id | select_type | table             | type | possible_keys | key  | key_len | ref  | rows  | Extra       |
+----+-------------+-------------------+------+---------------+------+---------+------+-------+-------------+
|  1 | SIMPLE      | objects_resources | ALL  | u             | NULL | NULL    | NULL | 10624 | Using where |
+----+-------------+-------------------+------+---------------+------+---------+------+-------+-------------+
1 row in set (0.00 sec)

Optimal plan:
mysql> explain SELECT id FROM objects_resources WHERE url='123202';
+----+-------------+-------------------+------+---------------+------+---------+-------+------+-------------+
| id | select_type | table             | type | possible_keys | key  | key_len | ref   | rows | Extra       |
+----+-------------+-------------------+------+---------------+------+---------+-------+------+-------------+
|  1 | SIMPLE      | objects_resources | ref  | u             | u    | 258     | const |    1 | Using where |
+----+-------------+-------------------+------+---------------+------+---------+-------+------+-------------+
1 row in set (0.01 sec)

How to repeat:
CREATE TABLE `objects_resources` (
  `id` int(11) NOT NULL default '0',
  `url` varchar(255) default NULL,
  PRIMARY KEY  (`id`),
  KEY `u` (`url`)
) ENGINE=MyISAM DEFAULT CHARSET=cp1251

insert into objects_resources values (1, '1');
insert into objects_resources values (2, '2');
insert into objects_resources values (3, '3');

explain select id from objects_resources where url=1;
explain select id from objects_resources where url='1';

Suggested fix:
convert int constant to varchar first, and use it for index lookup
[13 Nov 2007 10:48] Valeriy Kravchuk
Thank you for a problem report. Sorry, but this is not a bug, as manual clearly says (http://dev.mysql.com/doc/refman/5.0/en/type-conversion.html):

"In all other cases, the arguments are compared as floating-point (real) numbers."

So, if you DO NOT want varchar column to be converted (and that conversion leads to inability to use index), just use CAST(12345 as CHAR).