select v_data.*, GROUP_CONCAT(t_fa.Staff_Name) Staff_Name
from (select REC.Riqi_Date,
REC.Vehicle_Id,
t_vc.Vehicle_No,
REC.DeliveryLoading_Hdr_Id,
t_hd.DeliveryLoading_No,
REC.Operate_staff,
REC.Cart_check_State,
(select a.Value_Desc
from Fd_Field_Dtl a
where a.Field_Name = 'Cart_check_State'
and a.Value_Data = REC.Cart_check_State) Cart_check_StateName,
REC.ElectricalEquipment_State,
REC.Chassis_State,
REC.Engine_state,
REC.Exterior_State,
REC.Created_Time,
REC.Submit_Time,
REC.Repair_Item
from Rec_a REC,
Fd_Vb t_vc,
Bill_Dc t_hd
where REC.Vehicle_Id = t_vc.Vehicle_Id
and t_hd.Operator_Id = '174660684877367'
and REC.DeliveryLoading_Hdr_Id = t_hd.DeliveryLoading_Hdr_Id
and REC.Cart_check_State < 4
order by REC.Riqi_Date desc) v_data
LEFT JOIN Fd_Staff t_fa
on FIND_IN_SET(t_fa.Staff_Id, v_data.Operate_staff) > 0
GROUP BY v_data.DeliveryLoading_Hdr_Id
order by v_data.Riqi_Date;
查看执行计划
+----+--------------------+------------+--------+-----------------------------------------------------------+---------------------------+---------+--------------------------------+-------+-----------------------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+------------+--------+-----------------------------------------------------------+---------------------------+---------+--------------------------------+-------+-----------------------------------------------------------------+
| 1 | PRIMARY | | ALL | NULL | NULL | NULL | NULL | 741 | Using temporary; Using filesort |
| 1 | PRIMARY | t_fa | index | NULL | Staff_Name | 402 | NULL | 40141 | Using where; Using index; Using join buffer (Block Nested Loop) |
| 2 | DERIVED | REC | ALL | PRIMARY,DeliveryLoading_Hdr_Id,Cart_check_State | NULL | NULL | NULL | 741 | Using where; Using filesort |
| 2 | DERIVED | t_vc | eq_ref | PRIMARY,PK_Vehicle_Id | PRIMARY | 128 | TMP.REC.Vehicle_Id | 1 | NULL |
| 2 | DERIVED | t_hd | eq_ref | Pk_DeliveryLoading_Hdr_Id,Operator_Id,Bill_Hdr_Id_Vehicle | Pk_DeliveryLoading_Hdr_Id | 128 | TMP.REC.DeliveryLoading_Hdr_Id | 1 | Using where |
| 3 | DEPENDENT SUBQUERY | a | eq_ref | PRIMARY,UK_NAME_DATA | UK_NAME_DATA | 340 | const,TMP.REC.Cart_check_State | 1 | Using index condition |
+----+--------------------+------------+--------+-----------------------------------------------------------+---------------------------+---------+--------------------------------+-------+-----------------------------------------------------------------+
t_fa 表使用Staff_Name索引,消耗物理行数40141 ,整个SQL跑完要8秒。
利用”列转行”将FIND_IN_SET 转换成
FIND_IN_SET(t_fa.Staff_Id, v_data.Operate_staff)
改换为
t_fa.Staff_Id in (select replace(substring(substring_index(v_data.Operate_staff,
',',
s),
char_length(substring_index(v_data.Operate_staff,
',',
s - 1)) + 1),
',',
'') as f
from t_seq where s <= length(v_data.Operate_staff) - length(replace(v_data.Operate_staff, ',', '') )+1 )
其中t_seq如下
select * from t_seq ;
+——+
| s |
+——+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
| 7 |
| 8 |
| 9 |
| 10 |
+——+
转换之后整个SQL如下:
select v_data.*, GROUP_CONCAT(t_fa.Staff_Name) Staff_Name
from (select REC.Riqi_Date,
REC.Vehicle_Id,
t_vc.Vehicle_No,
REC.DeliveryLoading_Hdr_Id,
t_hd.DeliveryLoading_No,
REC.Operate_staff,
REC.Cart_check_State,
(select a.Value_Desc
from Fd_Field_Dtl a
where a.Field_Name = 'Cart_check_State'
and a.Value_Data = REC.Cart_check_State) Cart_check_StateName,
REC.ElectricalEquipment_State,
REC.Chassis_State,
REC.Engine_state,
REC.Exterior_State,
REC.Created_Time,
REC.Submit_Time,
REC.Repair_Item
from Rec_a REC,
Fd_Vb t_vc,
Bill_Dc t_hd
where REC.Vehicle_Id = t_vc.Vehicle_Id
and t_hd.Operator_Id = '174660684877367'
and REC.DeliveryLoading_Hdr_Id = t_hd.DeliveryLoading_Hdr_Id
and REC.Cart_check_State < 4
order by REC.Riqi_Date desc) v_data
LEFT JOIN Fd_Staff t_fa
on t_fa.Staff_Id in
(select replace(substring(substring_index(v_data.Operate_staff,
',',
s),
char_length(substring_index(v_data.Operate_staff,
',',
s - 1)) + 1),
',',
'') as f
from t_seq where s <= length(v_data.Operate_staff) - length(replace(v_data.Operate_staff, ',', '') )+1 )
GROUP BY v_data.DeliveryLoading_Hdr_Id
order by v_data.Riqi_Date;
查看执行计划:
+----+--------------------+------------+--------+-----------------------------------------------------------+---------------------------+---------+--------------------------------+------+--------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+------------+--------+-----------------------------------------------------------+---------------------------+---------+--------------------------------+------+--------------------------------------------------+
| 1 | PRIMARY | | ALL | NULL | NULL | NULL | NULL | 748 | Using temporary; Using filesort; Start temporary |
| 1 | PRIMARY | t_seq | ALL | NULL | NULL | NULL | NULL | 10 | Using where |
| 1 | PRIMARY | t_fa | eq_ref | PRIMARY,Staff_Id | PRIMARY | 128 | func | 1 | Using where; End temporary |
| 2 | DERIVED | REC | ALL | PRIMARY,DeliveryLoading_Hdr_Id,Cart_check_State | NULL | NULL | NULL | 748 | Using where; Using filesort |
| 2 | DERIVED | t_vc | eq_ref | PRIMARY,PK_Vehicle_Id | PRIMARY | 128 | TMP.REC.Vehicle_Id | 1 | NULL |
| 2 | DERIVED | t_hd | eq_ref | Pk_DeliveryLoading_Hdr_Id,Operator_Id,Bill_Hdr_Id_Vehicle | Pk_DeliveryLoading_Hdr_Id | 128 | TMP.REC.DeliveryLoading_Hdr_Id | 1 | Using where |
| 3 | DEPENDENT SUBQUERY | a | eq_ref | PRIMARY,UK_NAME_DATA | UK_NAME_DATA | 340 | const,TMP.REC.Cart_check_State | 1 | Using index condition |
+----+--------------------+------------+--------+-----------------------------------------------------------+---------------------------+---------+--------------------------------+------+--------------------------------------------------+
t_fa 使primary索引,消耗物理行数1,整个sql跑完只要0.04秒。