mysql left join 字段发生了隐式转换,索引失效,走的全表扫描
EXPLAIN select t.*,c.order_id,c.present_province_name,c.present_city_name, c.present_county_name,c.present_detail_address from (SELECT a.Id,a.DutyDate,a.CreateTime,a.PatientIdNo,a.PatientName,a.MobileNo,a.Status s,b.Name hosName,d.Name deptName FROM BI_AppointmentOrder a,BI_Hospital b,BI_Department d WHERE a.HospitalId in(4,140) AND a.DutyDate BETWEEN '2020-02-26' AND '2020-02-26' AND a.Status NOT in(2,8) AND a.HospitalId = b.Id AND a.DepartmentId = d.Id) t left join order_ext c on c.order_id=t.Id; +----+-------------+-------+------------+--------+------------------------------+----------------+---------+-----------------------------------+-------+----------+----------------------------------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+--------+------------------------------+----------------+---------+-----------------------------------+-------+----------+----------------------------------------------------+ | 1 | SIMPLE | b | NULL | range | PRIMARY | PRIMARY | 4 | NULL | 2 | 100.00 | Using where | | 1 | SIMPLE | a | NULL | ref | idx_HospitalId,idx_DDutyDate | idx_HospitalId | 4 | hp_cougar_transfer.b.Id | 1396 | 0.22 | Using where | | 1 | SIMPLE | d | NULL | eq_ref | PRIMARY | PRIMARY | 4 | hp_cougar_transfer.a.DepartmentId | 1 | 100.00 | NULL | | 1 | SIMPLE | c | NULL | ALL | idx_order_id | NULL | NULL | NULL | 94478 | 100.00 | Using where; Using join buffer (Block Nested Loop) | +----+-------------+-------+------------+--------+------------------------------+----------------+---------+-----------------------------------+-------+----------+----------------------------------------------------+
查看order_ext的表结构,发现 order_id varchar(50)
而BI_AppointmentOrder表中的Id字段是整形,left join order_ext c on c.order_id=t.Id 过程中发生了隐式转换,导致order_id列上的索引失效,从而走的全表扫描。
最终解决方案:
用concat()函数进行数据类型转换,将t.id从整形转换成字符串,再进行比较,最终结果无误,利用了索引
EXPLAIN select t.*,c.order_id,c.present_province_name,c.present_city_name, c.present_county_name,c.present_detail_address from (SELECT a.Id,a.DutyDate,a.CreateTime,a.PatientIdNo,a.PatientName,a.MobileNo,a.Status s,b.Name hosName,d.Name deptName FROM BI_AppointmentOrder a,BI_Hospital b,BI_Department d WHERE a.HospitalId in(4,140) AND a.DutyDate BETWEEN '2020-02-26' AND '2020-02-26' AND a.Status NOT in(2,8) AND a.HospitalId = b.Id AND a.DepartmentId = d.Id) t left join order_ext c on c.order_id=concat(t.Id); +----+-------------+-------+------------+--------+------------------------------+----------------+---------+-----------------------------------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+--------+------------------------------+----------------+---------+-----------------------------------+------+----------+-------------+ | 1 | SIMPLE | b | NULL | range | PRIMARY | PRIMARY | 4 | NULL | 2 | 100.00 | Using where | | 1 | SIMPLE | a | NULL | ref | idx_HospitalId,idx_DDutyDate | idx_HospitalId | 4 | hp_cougar_transfer.b.Id | 1396 | 0.22 | Using where | | 1 | SIMPLE | d | NULL | eq_ref | PRIMARY | PRIMARY | 4 | hp_cougar_transfer.a.DepartmentId | 1 | 100.00 | NULL | | 1 | SIMPLE | c | NULL | ref | idx_order_id | idx_order_id | 202 | func | 1 | 100.00 | Using where | +----+-------------+-------+------------+--------+------------------------------+----------------+---------+-----------------------------------+------+----------+-------------+