1. 程式人生 > 其它 >MySQL explain分析執行計劃

MySQL explain分析執行計劃

首先表結構為:

mysql> show create table film \G;
*************************** 1. row ***************************
       Table: film
Create Table: CREATE TABLE `film` (
  `film_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
  `title` varchar(128) NOT NULL,
  `description` text,
  `release_year` year(4
) DEFAULT NULL, `language_id` tinyint(3) unsigned NOT NULL, `original_language_id` tinyint(3) unsigned DEFAULT NULL, `rental_duration` tinyint(3) unsigned NOT NULL DEFAULT '3', `rental_rate` decimal(4,2) NOT NULL DEFAULT '4.99', `length` smallint(5) unsigned DEFAULT NULL, `replacement_cost`
decimal(5,2) NOT NULL DEFAULT '19.99', `rating` enum('G','PG','PG-13','R','NC-17') DEFAULT 'G', `special_features` set('Trailers','Commentaries','Deleted Scenes','Behind the Scenes') DEFAULT NULL, `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY
KEY (`film_id`), KEY `idx_title` (`title`), KEY `idx_fk_language_id` (`language_id`), KEY `idx_fk_original_language_id` (`original_language_id`), CONSTRAINT `fk_film_language` FOREIGN KEY (`language_id`) REFERENCES `language` (`language_id`) ON UPDATE CASCADE, CONSTRAINT `fk_film_language_original` FOREIGN KEY (`original_language_id`) REFERENCES `language` (`language_id`) ON UPDATE CASCADE ) ENGINE=InnoDB AUTO_INCREMENT=1001 DEFAULT CHARSET=utf8mb4 1 row in set (0.01 sec)

解釋查詢語句:

mysql> explain select * from film where rating > 9\G;
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: film
   partitions: NULL
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 1000
     filtered: 33.33
        Extra: Using where
1 row in set, 1 warning (0.01 sec)
  • select_type: 常見取值SIMPLE(簡單表,即不使用表連線和子查詢),PRIMARY(主查詢,即外層查詢),UNION(UNIION第二個及後面的查詢),SUBQUERY(子查詢中第一個select)
  • table:表名
  • type:查詢方式,一般有ALL,index,range,ref,eq_ref,const,system,NULL(從左往右,執行效率從差到好)
  1. type=ALL,全表掃描,不使用條件查詢,或查詢條件非索引欄位,上面例子即為全表掃描
  2. type=index,索引全掃描,MySQL匹配整個索引來查詢匹配的行
    mysql> explain select title from film\G
    *************************** 1. row ***************************
               id: 1
      select_type: SIMPLE
            table: film
       partitions: NULL
             type: index
    possible_keys: NULL
              key: idx_title
          key_len: 514
              ref: NULL
             rows: 1000
         filtered: 100.00
            Extra: Using index
    1 row in set, 1 warning (0.01 sec)
  3. type=range,索引範圍掃描,常見於<,<=,>,>=,between等操作
    mysql> explain select *  from payment where customer_id >= 300 and customer_id <= 350\G
    *************************** 1. row ***************************
               id: 1
      select_type: SIMPLE
            table: payment
       partitions: NULL
             type: range
    possible_keys: idx_fk_customer_id
              key: idx_fk_customer_id
          key_len: 2
              ref: NULL
             rows: 1350
         filtered: 100.00
            Extra: Using index condition
    1 row in set, 1 warning (0.01 sec)
  4. type=ref,使用非唯一索引掃描或唯一索引的字首掃描,返回某個單值的記錄行
    mysql> explain select * from payment where customer_id=350\G
    *************************** 1. row ***************************
               id: 1
      select_type: SIMPLE
            table: payment
       partitions: NULL
             type: ref
    possible_keys: idx_fk_customer_id
              key: idx_fk_customer_id
          key_len: 2
              ref: const
             rows: 23
         filtered: 100.00
            Extra: NULL
    1 row in set, 1 warning (0.01 sec)

    或在關聯查詢中,使用外來鍵連線

    mysql> explain select b.*, a.* from payment a, customer b where a.customer_id = b.customer_id \G
    *************************** 1. row ***************************
               id: 1
      select_type: SIMPLE
            table: b
       partitions: NULL
             type: ALL
    possible_keys: PRIMARY
              key: NULL
          key_len: NULL
              ref: NULL
             rows: 599
         filtered: 100.00
            Extra: NULL
    *************************** 2. row ***************************
               id: 1
      select_type: SIMPLE
            table: a
       partitions: NULL
             type: ref
    possible_keys: idx_fk_customer_id
              key: idx_fk_customer_id
          key_len: 2
              ref: sakila.b.customer_id
             rows: 26
         filtered: 100.00
            Extra: NULL
    2 rows in set, 1 warning (0.01 sec)
  5. type=eq_ref,類似ref,區別是使用的索引是唯一索引,對於每個索引鍵值,表中只有一條記錄匹配;簡單地說就是多表連線中使用primary key或者unique index作為關聯條件
    mysql> explain select * from film a, film_text b where a.film_id = b.film_id\G
    *************************** 1. row ***************************
               id: 1
      select_type: SIMPLE
            table: b
       partitions: NULL
             type: ALL
    possible_keys: PRIMARY
              key: NULL
          key_len: NULL
              ref: NULL
             rows: 1000
         filtered: 100.00
            Extra: NULL
    *************************** 2. row ***************************
               id: 1
      select_type: SIMPLE
            table: a
       partitions: NULL
             type: eq_ref
    possible_keys: PRIMARY
              key: PRIMARY
          key_len: 2
              ref: sakila.b.film_id
             rows: 1
         filtered: 100.00
            Extra: Using where
    2 rows in set, 1 warning (0.01 sec)
  6. type=const/system,單表最多有一行匹配,查詢起來非常迅速,例如根據主鍵或唯一索引查詢
    mysql> explain select * from payment where payment_id = 30\G
    *************************** 1. row ***************************
               id: 1
      select_type: SIMPLE
            table: payment
       partitions: NULL
             type: const
    possible_keys: PRIMARY
              key: PRIMARY
          key_len: 2
              ref: const
             rows: 1
         filtered: 100.00
            Extra: NULL
    1 row in set, 1 warning (0.01 sec)
  7. type=NULL表示不用訪問表或索引,直接就能返回
    mysql> explain select 1 from dual where 1\G
    *************************** 1. row ***************************
               id: 1
      select_type: SIMPLE
            table: NULL
       partitions: NULL
             type: NULL
    possible_keys: NULL
              key: NULL
          key_len: NULL
              ref: NULL
             rows: NULL
         filtered: NULL
            Extra: No tables used
    1 row in set, 1 warning (0.01 sec)
  • possible_keys:表示查詢時可能會用到的索引
  • keys:表示查詢時實際用到的索引
  • key_len:索引欄位的長度
  • rows:掃描的行數,行數大小影響查詢效率
  • Extra:執行情況的說明和描述