1. 程式人生 > >MySQL SQL一種常用的優化方法

MySQL SQL一種常用的優化方法

下面的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