檢視一個正在執行的sql的執行計劃(explain for connection processlist_id)

sun_ashe發表於2018-10-25

線上往往會出現如下這種情況

一條sql很慢,但是寫的太長了,沒辦法複製出來,但是想看他的執行計劃,怎麼辦呢?幸好MySQL5.7提供了額外的explain方法

| 25977372 | ashe   | 111.111.1.111:41102  | ashe     | Query            |    2448 | updating                                                      | delete from ashe
     WHERE CUSTOMER_ID IN
      (
        2656596635
      ,
        26565 |

可以通過explain for connection來看這個執行緒的執行計劃

mysql> explain for connection 25977372\G
*************************** 1. row ***************************
           id: 1
  select_type: DELETE
        table: ashe
   partitions: NULL
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 106665797
     filtered: 100.00
        Extra: Using where
1 row in set (0.00 sec)

這個表的CUSTOMER_ID欄位是有索引的,可以看到,由於條件中的in條件太多,導致MySQL走全表掃描了。

mysql> show create table ashe\G
*************************** 1. row ***************************
       Table: ashe
Create Table: CREATE TABLE `ashe` (
  `CUSTOMER_ID` bigint(18) NOT NULL AUTO_INCREMENT,
  `ACCT_ID` varchar(40) DEFAULT NULL   ,
  `NAME` varchar(255) DEFAULT NULL ,
  `STATUS` int(2) DEFAULT NULL  ,
  `SCORE` int(6) DEFAULT NULL  ,
  `COMMENTS` varchar(400) DEFAULT NULL ,
  `READONLY` int(1) DEFAULT NULL ,
  `CHECK_TIME` timestamp NULL DEFAULT NULL ,
  `CREATE_TIME` timestamp NULL DEFAULT '0000-00-00 00:00:00'  ,
  `UPDATE_TIME` timestamp NULL DEFAULT '0000-00-00 00:00:00'  ,
  `VALUE` longtext COMMENT 'JSON',
  `MODIFIER` int(8) DEFAULT NULL ,
  `GROUP_TYPE` int(1) DEFAULT NULL ,
  `CERTIFICATE_NO` varchar(128) DEFAULT NULL ,
  `PHONE` varchar(128) DEFAULT NULL ,
  `DSNAME` varchar(100) DEFAULT NULL ,
  `AUDIT_STATUS` int(1) DEFAULT '0'  ,
  PRIMARY KEY (`CUSTOMER_ID`),
  KEY `index_accout` (`ACCT_ID`) USING BTREE,
  KEY `index_cer` (`CERTIFICATE_NO`) USING BTREE,
  KEY `index_phone` (`PHONE`) USING BTREE,
  KEY `index_name` (`DSNAME`) USING BTREE,
  KEY `index_time` (`CHECK_TIME`) USING BTREE,
  KEY `index_time_score` (`CHECK_TIME`,`SCORE`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=2808276116 DEFAULT CHARSET=utf8 KEY_BLOCK_SIZE=8
1 row in set (0.00 sec)

RD也是個人才,大概看了下in中的條件,如下,為毛要寫成in呢?

PROCESSLIST_INFO: delete from ashe
     WHERE CUSTOMER_ID IN
      (
        2656596635
      ,
        2656596636
      ,
        2656596637
      ,
        2656596639
      ,
        2656596640
      ,
        2656596641
      ,
        2656596642
      ,
        2656596643
      ,
        2656596644
      ,
        2656596645
      ,
        2656596646
      ,
        2656596647
      ,
        2656596649
      ,
        2656596650
      ,
        2656596651
      ,
        2656596652
      ,
        2656596653

優化

可以將in的個數降低到100以內,或者直接單條刪除吧,不會很慢。
可以參照這篇 https://blog.csdn.net/sun_ashe/article/details/83378728

相關文章