问题:
项目使用Activiti进行工单业务开发时 ,将历史任务实例表( act_hi_taskinst )和催单记录表(tbl_urgency_recd)进行left join关联开发时,发现已经建了索引,但是执行计划里显示没有使用索引。
原因:
所有的关联的字段的字符集不一样,导致无法使用索引。
具体过程如下:
SQL的执行计划:
Extra列,Range checked for each record (index map: 0x2)的意思为没有合适的索引可用。以下为《高性能MySQL》一书的解释:
但是,两个表对应的字段都是建有索引:
act_hi_taskinst:
tbl_urgency_recd:
查看两个表的字段属性:
tbl_urgency_recd:
act_hi_taskinst:
tbl_urgency_recd表字段task_id字符集为:utf8_general_ci。
act_hi_taskinst表字段ID_的字符集为:utf8_bin。
将tbl_urgency_recd表字段task_id字符集修改为:utf8_bin。
修改完,再执行explain,结果入下。
显示,已使用索引,关联类型(type)由ALL(全表扫秒)变为ref(索引访问)。
另外,在这记录下mysql的常见字符集区别,用以备查:
utf8_bin将字符串中的每个字符用二进制数据存储,区分大小写。
utf8_genera_ci不区分大小写,ci为case insensitive的缩写,即大小写不敏感,为utf8默认编码。
utf8_general_cs区分大小写,cs为case sensitive的缩写,即大小写敏感。