MySQL SQL一種常用的優化方法
阿新 • • 發佈:2019-02-16
下面的SQL 20多秒。如何優化:
SELECT ................
FROM gg_bm_o_order o_order
LEFT JOIN gg_bm_u_app_user app_user ON app_user.user_code =
o_order.user_code
LEFT JOIN gg_om_dm_site_img m_site_img ON m_site_img.SITE_CODE =
o_order.SITE_CODE
AND m_site_img.SORT_NO = 1
LEFT JOIN gg_om_dm_charging_gun charging_gun ON charging_gun.CHARGING_PILE_CODE =
o_order.charging_pile_code
AND charging_gun.CHARGING_PILE_INTER_CODE =
o_order.charging_pile_inter_code
LEFT JOIN gg_om_dm_charging_pile charging_pile ON charging_pile.CHARGING_PILE_CODE = o_order.charging_pile_code
LEFT JOIN gg_pay_invoice_order_relation invoice_order ON invoice_order.ORDER_CODE = o_order.order_code
LEFT JOIN gg_bm_o_order_suspend o_suspend ON o_suspend.order_code = o_order.order_code
WHERE 1 = 1 AND o_order.IS_DELETE <> 2
and o_order.order_state = 4
AND (DATE_FORMAT(o_order.order_end_time,'%Y-%m-%d') <= '2018-01-21' AND DATE_FORMAT(o_order.order_end_time,'%Y-%m-%d') >= '2017-01-21')
GROUP BY o_order.ORDER_CODE
ORDER BY orderEndTime desc limit 0,20
id select_type table type possible_keys key key_len ref rows Extra
------ ----------- ------------- ------ -------------------------------------------------------- ------------------------------- ------- --------------------------------------------------------------------- ------ ----------------------------------------------------
1 SIMPLE o_order ALL IDX_ORDER_CODE (NULL) (NULL) (NULL) 509537 Using where; Using temporary; Using filesort
1 SIMPLE app_user ref AK_USER_CODE AK_USER_CODE 99 evic.o_order.USER_CODE 1 (NULL)
1 SIMPLE m_site_img ref AK_KEY_SITE_CODE_SORT_NO,FK_IMG_SITE_CODE AK_KEY_SITE_CODE_SORT_NO 104 evic.o_order.SITE_CODE,const 1 (NULL)
1 SIMPLE charging_gun ref AK_KEY_CHARGING_PILE_INTER_CODE,Index_DM_PILE_INTER_CODE AK_KEY_CHARGING_PILE_INTER_CODE 108 evic.o_order.CHARGING_PILE_CODE,evic.o_order.CHARGING_PILE_INTER_CODE 1 (NULL)
1 SIMPLE charging_pile ref IDX_CHARGING_PILE_CODE IDX_CHARGING_PILE_CODE 99 evic.o_order.CHARGING_PILE_CODE 1 (NULL)
1 SIMPLE invoice_order ALL IX_INVOICEORDER_ORDERCODE (NULL) (NULL) (NULL) 1 Using where; Using join buffer (Block Nested Loop)
1 SIMPLE o_suspend ref IX_ORDERSUSPEND_ORDERCODE IX_ORDERSUSPEND_ORDERCODE 99 evic.o_order.ORDER_CODE 1 Using where
a.首先索引列進行了運算,用不到索引。
b.現在主表中排序查出20條資料,因為這一過程可以用到索引,所以非常快。
c.與其他表關聯,可能會產生更多的資料,所以要group by一下,MySQL中的group by 居然是去重的,還要按照時間排序。
SQL中有兩個limit,第一個limit是與頁面的分頁同步,第二個limit只是取多少資料。
SELECT ..............
FROM (SELECT .......
FROM gg_bm_o_order o_order
WHERE IS_DELETE <> 2
AND order_state = 4
AND order_end_time >=STR_TO_DATE(CONCAT('2017-01-21', ' 00:00:00'),'%Y-%m-%d %H:%i:%s')
AND order_end_time <=STR_TO_DATE(CONCAT('2018-01-21', ' 23:59:59'),'%Y-%m-%d %H:%i:%s')
ORDER BY order_end_time DESC LIMIT 0, 20) o_order
LEFT JOIN gg_bm_u_app_user app_user ON app_user.user_code = o_order.user_code
LEFT JOIN gg_om_dm_site_img m_site_img ON m_site_img.SITE_CODE =o_order.SITE_CODE
AND m_site_img.SORT_NO = 1
LEFT JOIN gg_om_dm_charging_gun charging_gun ON charging_gun.CHARGING_PILE_CODE =
o_order.charging_pile_code
AND charging_gun.CHARGING_PILE_INTER_CODE =
o_order.charging_pile_inter_code
LEFT JOIN gg_om_dm_charging_pile charging_pile ON charging_pile.CHARGING_PILE_CODE =
o_order.charging_pile_code
LEFT JOIN gg_pay_invoice_order_relation invoice_order ON invoice_order.ORDER_CODE =
o_order.order_code
LEFT JOIN gg_bm_o_order_suspend o_suspend ON o_suspend.order_code = o_order.order_code
GROUP BY o_order.order_code
ORDER BY o_order.order_end_time
LIMIT 0,20;
id select_type TABLE TYPE possible_keys KEY key_len ref ROWS Extra
------ ----------- ------------- ------ -------------------------------------------------------- ------------------------------- ------- ----------------------------------------------------------- ------ ----------------------------------------------------
1 PRIMARY <derived2> ALL (NULL) (NULL) (NULL) (NULL) 20 USING TEMPORARY; USING filesort
1 PRIMARY app_user ref AK_USER_CODE AK_USER_CODE 99 o_order.user_code 1 (NULL)
1 PRIMARY m_site_img ref AK_KEY_SITE_CODE_SORT_NO,FK_IMG_SITE_CODE AK_KEY_SITE_CODE_SORT_NO 104 o_order.site_code,const 1 (NULL)
1 PRIMARY charging_gun ref AK_KEY_CHARGING_PILE_INTER_CODE,Index_DM_PILE_INTER_CODE AK_KEY_CHARGING_PILE_INTER_CODE 108 o_order.charging_pile_code,o_order.charging_pile_inter_code 1 (NULL)
1 PRIMARY charging_pile ref IDX_CHARGING_PILE_CODE IDX_CHARGING_PILE_CODE 99 o_order.charging_pile_code 1 (NULL)
1 PRIMARY invoice_order ALL IX_INVOICEORDER_ORDERCODE (NULL) (NULL) (NULL) 1 USING WHERE; USING JOIN buffer (Block Nested LOOP)
1 PRIMARY o_suspend ref IX_ORDERSUSPEND_ORDERCODE IX_ORDERSUSPEND_ORDERCODE 99 o_order.order_code 1 USING WHERE
2 DERIVED o_order RANGE IDX_ORDER_ORDER_END_TIME IDX_ORDER_ORDER_END_TIME 6 (NULL) 255038 USING INDEX CONDITION; USING WHERE
SELECT ................
FROM gg_bm_o_order o_order
LEFT JOIN gg_bm_u_app_user app_user ON app_user.user_code =
o_order.user_code
LEFT JOIN gg_om_dm_site_img m_site_img ON m_site_img.SITE_CODE =
o_order.SITE_CODE
AND m_site_img.SORT_NO = 1
LEFT JOIN gg_om_dm_charging_gun charging_gun ON charging_gun.CHARGING_PILE_CODE =
o_order.charging_pile_code
AND charging_gun.CHARGING_PILE_INTER_CODE =
o_order.charging_pile_inter_code
LEFT JOIN gg_om_dm_charging_pile charging_pile ON charging_pile.CHARGING_PILE_CODE = o_order.charging_pile_code
LEFT JOIN gg_pay_invoice_order_relation invoice_order ON invoice_order.ORDER_CODE = o_order.order_code
LEFT JOIN gg_bm_o_order_suspend o_suspend ON o_suspend.order_code = o_order.order_code
WHERE 1 = 1 AND o_order.IS_DELETE <> 2
and o_order.order_state = 4
AND (DATE_FORMAT(o_order.order_end_time,'%Y-%m-%d') <= '2018-01-21' AND DATE_FORMAT(o_order.order_end_time,'%Y-%m-%d') >= '2017-01-21')
GROUP BY o_order.ORDER_CODE
ORDER BY orderEndTime desc limit 0,20
id select_type table type possible_keys key key_len ref rows Extra
------ ----------- ------------- ------ -------------------------------------------------------- ------------------------------- ------- --------------------------------------------------------------------- ------ ----------------------------------------------------
1 SIMPLE o_order ALL IDX_ORDER_CODE (NULL) (NULL) (NULL) 509537 Using where; Using temporary; Using filesort
1 SIMPLE app_user ref AK_USER_CODE AK_USER_CODE 99 evic.o_order.USER_CODE 1 (NULL)
1 SIMPLE m_site_img ref AK_KEY_SITE_CODE_SORT_NO,FK_IMG_SITE_CODE AK_KEY_SITE_CODE_SORT_NO 104 evic.o_order.SITE_CODE,const 1 (NULL)
1 SIMPLE charging_gun ref AK_KEY_CHARGING_PILE_INTER_CODE,Index_DM_PILE_INTER_CODE AK_KEY_CHARGING_PILE_INTER_CODE 108 evic.o_order.CHARGING_PILE_CODE,evic.o_order.CHARGING_PILE_INTER_CODE 1 (NULL)
1 SIMPLE charging_pile ref IDX_CHARGING_PILE_CODE IDX_CHARGING_PILE_CODE 99 evic.o_order.CHARGING_PILE_CODE 1 (NULL)
1 SIMPLE invoice_order ALL IX_INVOICEORDER_ORDERCODE (NULL) (NULL) (NULL) 1 Using where; Using join buffer (Block Nested Loop)
1 SIMPLE o_suspend ref IX_ORDERSUSPEND_ORDERCODE IX_ORDERSUSPEND_ORDERCODE 99 evic.o_order.ORDER_CODE 1 Using where
a.首先索引列進行了運算,用不到索引。
b.現在主表中排序查出20條資料,因為這一過程可以用到索引,所以非常快。
c.與其他表關聯,可能會產生更多的資料,所以要group by一下,MySQL中的group by 居然是去重的,還要按照時間排序。
SQL中有兩個limit,第一個limit是與頁面的分頁同步,第二個limit只是取多少資料。
SELECT ..............
FROM (SELECT .......
FROM gg_bm_o_order o_order
WHERE IS_DELETE <> 2
AND order_state = 4
AND order_end_time >=STR_TO_DATE(CONCAT('2017-01-21', ' 00:00:00'),'%Y-%m-%d %H:%i:%s')
AND order_end_time <=STR_TO_DATE(CONCAT('2018-01-21', ' 23:59:59'),'%Y-%m-%d %H:%i:%s')
ORDER BY order_end_time DESC LIMIT 0, 20) o_order
LEFT JOIN gg_bm_u_app_user app_user ON app_user.user_code = o_order.user_code
LEFT JOIN gg_om_dm_site_img m_site_img ON m_site_img.SITE_CODE =o_order.SITE_CODE
AND m_site_img.SORT_NO = 1
LEFT JOIN gg_om_dm_charging_gun charging_gun ON charging_gun.CHARGING_PILE_CODE =
o_order.charging_pile_code
AND charging_gun.CHARGING_PILE_INTER_CODE =
o_order.charging_pile_inter_code
LEFT JOIN gg_om_dm_charging_pile charging_pile ON charging_pile.CHARGING_PILE_CODE =
o_order.charging_pile_code
LEFT JOIN gg_pay_invoice_order_relation invoice_order ON invoice_order.ORDER_CODE =
o_order.order_code
LEFT JOIN gg_bm_o_order_suspend o_suspend ON o_suspend.order_code = o_order.order_code
GROUP BY o_order.order_code
ORDER BY o_order.order_end_time
LIMIT 0,20;
id select_type TABLE TYPE possible_keys KEY key_len ref
------ ----------- ------------- ------ -------------------------------------------------------- ------------------------------- ------- ----------------------------------------------------------- ------ ----------------------------------------------------
1 PRIMARY <derived2> ALL (NULL) (NULL) (NULL) (NULL) 20 USING TEMPORARY; USING filesort
1 PRIMARY app_user ref AK_USER_CODE AK_USER_CODE 99 o_order.user_code 1 (NULL)
1 PRIMARY m_site_img ref AK_KEY_SITE_CODE_SORT_NO,FK_IMG_SITE_CODE AK_KEY_SITE_CODE_SORT_NO 104 o_order.site_code,const 1 (NULL)
1 PRIMARY charging_gun ref AK_KEY_CHARGING_PILE_INTER_CODE,Index_DM_PILE_INTER_CODE AK_KEY_CHARGING_PILE_INTER_CODE 108 o_order.charging_pile_code,o_order.charging_pile_inter_code 1 (NULL)
1 PRIMARY charging_pile ref IDX_CHARGING_PILE_CODE IDX_CHARGING_PILE_CODE 99 o_order.charging_pile_code 1 (NULL)
1 PRIMARY invoice_order ALL IX_INVOICEORDER_ORDERCODE (NULL) (NULL) (NULL) 1 USING WHERE; USING JOIN buffer (Block Nested LOOP)
1 PRIMARY o_suspend ref IX_ORDERSUSPEND_ORDERCODE IX_ORDERSUSPEND_ORDERCODE 99 o_order.order_code 1 USING WHERE
2 DERIVED o_order RANGE IDX_ORDER_ORDER_END_TIME IDX_ORDER_ORDER_END_TIME 6 (NULL) 255038 USING INDEX CONDITION; USING WHERE