mysql> CREATE TABLE `tradelog` (`id` int(11) NOT NULL,`tradeid` varchar(32) DEFAULT NULL,`operator` int(11) DEFAULT NULL,`t_modified` datetime DEFAULT NULL,PRIMARY KEY (`id`),KEY `tradeid` (`tradeid`),KEY `t_modified` (`t_modified`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
1、使用函数
2、隐式类型转换
select * from tradelog where tradeid=123123;
如果字段类型与传入的值的类型不一致,就会发生类型转换,上边的sql,tradeid为varchar,而传入的为整型,所以需要进行类型转换。
转换的规则
看 select ‘10’ > 9的结果
- 如果结果为 1 ,那么就说明是字符串转成了整型
- 如果结果为0,那么就说明是整型转换成了字符型

说明为字符型转换为了整型,那么针对上边的SQL就是,字段的值做了类型转换,就相当于
mysql> select * from tradelog where CAST(tradid AS signed int) = 123123;
使用了函数,因此不走索引.
如果tradid字段是int,而sql是trandid = ‘1231312’,那么会走索引吗,答案是类型发生了转换,但是是传入的值的类型发生了转换,从字符型转换为int,字段并没有使用函数,因此还是会走索引
3、隐式字符编码转换
再创建一张关联表
mysql> CREATE TABLE `trade_detail` (
`id` int(11) NOT NULL,
`tradeid` varchar(32) DEFAULT NULL,
`trade_step` int(11) DEFAULT NULL, /*操作步骤*/
`step_info` varchar(32) DEFAULT NULL, /*步骤信息*/
PRIMARY KEY (`id`),
KEY `tradeid` (`tradeid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
两个表的字符集分别是utf8mb4和utf8;
utf8mb4是utf8的超集,当这两个类型的字符串在作比较的时候, MySQL内部是先吧utf8字符串转换成utf8mb4字符集再作比较。
如果要查询tradelog表的id=2的tradeid的所有操作步骤,sql要这么写
mysql> select d.* from tradelog l, trade_detail d where d.tradeid=l.tradeid and l.id=2; /*语句Q1*/

查询表tradelog是使用了索引的,但是查询detail没有使用索引,为什么?
因为tradelog的tradeid字段为utfmb4,执行d.tradeid=l.tradeid的时候,内部d.tradeid相当于执行了CONVERT(traideid USING utf8mb4),字段使用了函数,因此不走索引。
解决方法
1、可以将传入的值的字符类型进行转换,转换成和字段类型一致的,就会重新使用索引
2、可以将两张表的字符集改为一致的
