数据类型不一致会导致索引失效
下面案例中fk_do_depart 是varchar类型的, 如果关联的字段不是varchar类型的话会导致索引失效
用相同的数据类型关联
注意观察 fk_do_depart = ‘10001108’ ,两个都是varchar类型的
EXPLAIN
SELECT do.fk_definition_id, t3.fk_org_region_id
FROM t_user_account t1
INNER JOIN t_relation_account_role t2 ON t1.pk_account_id = t2.fk_account_Id
INNER JOIN t_relation_account_organization_region t3 ON t1.pk_account_id = t3.fk_account_id
INNER JOIN t_approval_do do
ON do.fk_do_depart = '10001108' AND do.account_month = '2020-12'
AND do.fk_do_role = 12
WHERE t1.ds = 0
AND t2.ds = 0
AND t2.fk_role_id = 12
AND t1.account_state = 1
AND t3.ds = 0
AND t3.data_state = 1
AND t1.mobile = 13688888888;
执行结果:
id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
1 | SIMPLE | do | ref | idx_definition_depart_role | idx_definition_depart_role | 133 | const,const | 74 | Using where; Using index |
1 | SIMPLE | t1 | eq_ref | PRIMARY,UI_ur_tuseraccot | PRIMARY | 4 | wxapp.t2.fk_account_Id | 1 | Using where |
1 | SIMPLE | t2 | ref | FK_Reference_19,FK_Reference_4 | FK_Reference_4 | 5 | const | 1808 | Using where |
1 | SIMPLE | t3 | ref | FK_Reference_20 | FK_Reference_20 | 5 | wxapp.t2.fk_account_Id | 1 | Using where |
结果可以发现 do这个表 type是 ref , ref是 const,const rows扫描了74行
用不同的数据类型关联
注意观察 这个SQL和上面的SQL几乎是一模一样的,只是 fk_do_depart = 10001108 和上面的不一样,fk_do_depart 是varchar类型的, 而后面 10001108是数字
EXPLAIN
SELECT do.fk_definition_id, t3.fk_org_region_id
FROM t_user_account t1
INNER JOIN t_relation_account_role t2 ON t1.pk_account_id = t2.fk_account_Id
INNER JOIN t_relation_account_organization_region t3 ON t1.pk_account_id = t3.fk_account_id
INNER JOIN t_approval_do do
ON do.fk_do_depart = 10001108 AND do.account_month = '2020-12'
AND do.fk_do_role = 12
WHERE t1.ds = 0
AND t2.ds = 0
AND t2.fk_role_id = 12
AND t1.account_state = 1
AND t3.ds = 0
AND t3.data_state = 1
AND t1.mobile = 13688888888;
执行结果:
id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
1 | SIMPLE | do | index | idx_definition_depart_role | idx_definition_depart_role | 213 | NULL | 3524 | Using where; Using index; Using join buffer (Block Nested Loop) |
1 | SIMPLE | t1 | eq_ref | PRIMARY,UI_ur_tuseraccot | PRIMARY | 4 | wxapp.t2.fk_account_Id | 1 | Using where |
1 | SIMPLE | t2 | ref | FK_Reference_19,FK_Reference_4 | FK_Reference_4 | 5 | const | 1808 | Using where |
1 | SIMPLE | t3 | ref | FK_Reference_20 | FK_Reference_20 | 5 | wxapp.t2.fk_account_Id | 1 | Using where |
结果可以发现do 的 type是index ref是null. rows扫了3524行,
结论
首先案例的fk_do_depart 字段是varchar类型的
fk_do_depart = ‘10001108’ 中do表的type是ref 而 fk_do_depart = 10001108 中do表的的type是index类型的
fk_do_depart = ‘10001108’ 比 fk_do_depart = 10001108 多扫了3000多行, 这还只是我本地的数据库,如果是线上数据库的话,数据量很庞大的话,那么这多扫描的行数可能会很大. 那么性能会差距巨大.