MySQL查詢中Sending data佔用大量時間的問題處理

ywxj_001發表於2019-10-16
原SQL執行計劃:
EXPLAIN
SELECT tm.id,
tm.to_no ,
tm.source_website_id ,
tm.warehouse_name ,
tm.target_website_id ,
tm.channel_name ,
tm.sale_channel_name ,
ti.product_basic_id ,
ti.product_basic_no ,
ti.product_basic_name ,
ti.tax_rate ,
ti.sale_tax_rate ,
ti.quantity/ti.main_aux_ratio quantity ,
ti.unit_cost * ti.main_aux_ratio unit_cost,
ti.unit_cost * IFNULL(ti.quantity,0) amount,
ti.received_qty,
tm.po_no ,
tm.source_website_name,
tm.target_website_name,
createUser.user_name create_user_name,
auditUser.user_name audit_user_name,
outUser.user_name out_user_name,
DATE_FORMAT(tm.create_time, '%Y/%m/%d %H:%i:%s') create_time ,
DATE_FORMAT(tp.audit_time, '%Y/%m/%d %H:%i:%s') audit_time ,
DATE_FORMAT(tp.out_time, '%Y/%m/%d %H:%i:%s') out_time ,
tm.`status`,
DATE_FORMAT(tp.in_time, '%Y/%m/%d %H:%i:%s') receive_time,
IFNULL(ti.return_qty/ti.main_aux_ratio, 0) return_qty,
ti.unit_cost * IFNULL(ti.received_qty,0) return_amount,
DATE_FORMAT(td.production_date, '%Y/%m/%d') production_date,
td.location_name off_location_name FROM transfer_master AS tm
LEFT JOIN transfer_item AS ti ON tm.id = ti.to_id
LEFT JOIN transfer_detail td ON tm.id = td.transfer_id AND ti.product_basic_id = td.product_basic_id
LEFT JOIN transfer_operation tp ON tp.transfer_id = tm.id
LEFT JOIN sys_user createUser ON createUser.sysno = tm.create_user_id
LEFT JOIN sys_user auditUser ON auditUser.sysno = tp.audit_user_id
LEFT JOIN sys_user outUser ON outUser.sysno = tp.out_user_id WHERE 1 = 1 AND tm.source_website_id IN (3) AND tm.status = 110 AND tm.create_time >= '2019-04-01' AND tm.create_time < '2019-10-01' ORDER BY tm.create_time DESC

MySQL查詢中Sending data佔用大量時間的問題處理以上SQL很多列沒有用到索引。

1 queries executed, 1 success, 0 errors, 0 warnings


查詢:SELECT tm.id, tm.to_no , tm.source_website_id , tm.warehouse_name , tm.target_website_id , tm.channel_name , tm.sale_channel_nam...


共 1000 行受到影響


執行耗時   : 1 min 10 sec

傳送時間   : 0.016 sec

總耗時      : 1 min 10 sec

MySQL查詢中Sending data佔用大量時間的問題處理

Sending data花費時間最長。


“Sending data”狀態的含義,原來這個狀態的名稱很具有誤導性,所謂的“Sending data”並不是單純的傳送資料,而是包括“收集 + 傳送 資料”。

這裡的關鍵是為什麼要收集資料,原因在於:mysql使用“索引”完成查詢結束後,mysql得到了一堆的行id,如果有的列並不在索引中,mysql需要重新到“資料行”上將需要返回的資料讀取出來返回個客戶端。



對欄位新增索引。

第一條索引:ALTER TABLE `transfer_detail` ADD INDEX idx_transfer_id (`transfer_id`);

第二條索引:ALTER TABLE `transfer_item` ADD INDEX idx_to_id (`to_id`);

第三條索引:ALTER TABLE `transfer_operation` ADD INDEX idx_transfer_id (`transfer_id`);


第一條索引:ALTER TABLE `transfer_detail` ADD INDEX idx_transfer_id (`transfer_id`);

執行計劃:

MySQL查詢中Sending data佔用大量時間的問題處理消耗時間:

MySQL查詢中Sending data佔用大量時間的問題處理


加第二條索引: ALTER TABLE `transfer_item` ADD INDEX idx_to_id (`to_id`);

執行計劃:

MySQL查詢中Sending data佔用大量時間的問題處理 消耗時間:

MySQL查詢中Sending data佔用大量時間的問題處理


加第三條索引: ALTER TABLE `transfer_operation` ADD INDEX idx_transfer_id (`transfer_id`);

執行計劃:

MySQL查詢中Sending data佔用大量時間的問題處理 消耗時間:

MySQL查詢中Sending data佔用大量時間的問題處理

最佳化完成。


tm表的條件欄位資料分佈不均勻,不建議加索引。


對條件欄位新增索引後,Sending data消耗時間大幅下降。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/22996654/viewspace-2660182/,如需轉載,請註明出處,否則將追究法律責任。

相關文章