left join查询,主表13万条数据副表8000条,连接条件不是主键,怎么优化查询?

img


像这个查询,cc_sjz_3有13万条数据,biz_type = ‘bank’ 它也有11万多条,cc_company_branch根据comb_name分组后有8000条数据,去进行左连接,连接条件不是主键,给主表cc_sjz_3的comb_name添加了索引发现没有使用上

img


像这种怎么去优化呢?

使用INNER JOIN代替LEFT JOIN
如果cc_sjz_3表中所有的comb_name都存在于cc_company_branch表中,可以使用INNER JOIN代替LEFT JOIN,这样可以减少连接操作,提高查询效率。

将cc_company_branch表中的comb_name添加索引
虽然左连接的连接条件不是主键,但是如果cc_company_branch表中的comb_name添加了索引,可以提高连接操作的效率。

使用子查询代替左连接
如果以上两种优化方案都无法提高查询效率,可以考虑使用子查询代替左连接,将cc_company_branch表的数据先查询出来,再与cc_sjz_3表进行连接操作。例如:

SELECT MD5(UUID()) card_id,
t1.phone,
t1.new_card_no,
t3.comb_id,
t1.person_name,
t1.id_card,
t1.biz_type,
t1.open_time,
'NOT DELETE' delete_flag
FROM cc_sjz_3 t1,
(SELECT comb_id, comb_name FROM cc_company_branch GROUP BY comb_name) t3
WHERE t1.biz_type = 'bank'
AND t1.comb_name = t3.comb_name;

这种方式可以避免左连接的效率问题,但是需要注意子查询的数据量不能太大,否则会影响整个查询的效率。

1、要想使用索引,不应该在表 cc_sjz_3 的 comb_name 添加,而是需要在表 cc_company_branch 表中的 comb_name 字段添加,但你使用了 group by一次,因此即便添加也仍然不会使用
2、由于你需要从 cc_sjz_3 表中提取11万条数据,而总数才13万,所以这个表无论如何都不会使用索引
3、实际上你只提取了表 cc_company_branch 的 comb_id 字段,因此,直接使用子查询即可,而且还可以使用其中 comb_name 字段的索引(如果有建立的话),SQL类似:

SELECT MD5( UUID( ) ) card_id
     , t1.phone
     , t1.new_card_no
     , ( SELECT comb_id FROM cc_company_branch t2 WHERE t1.comb_name = t2.comb_name LIMIT 1 ) comb_id
     , t1.person_name
     , t1.id_card
     , t1.biz_type
     , t1.open_time
     , 'NOT DELETE' delete_flag
  FROM cc_sjz_3 t1
 WHERE t1.biz_type = 'bank';