mysql執行計劃explain學習筆記

語法

explain +執行的sql語句;

快速開始

  1. 查看mysql的狀態,瞭解當前mysql server的版本等信息
    mysql> status;
    mysql Ver 14.14 Distrib 5.7.25, for linux-glibc2.12 (x86_64) using EditLine wrapper
    Connection id: 12364
    Current database: him
    Current user: root@localhost
    SSL: Not in use
    Current pager: stdout
    Using outfile: ‘’
    Using delimiter: ;
    Server version: 5.7.25 MySQL Community Server (GPL)
    Protocol version: 10
    Connection: Localhost via UNIX socket
    Server characterset: latin1
    Db characterset: latin1
    Client characterset: utf8
    Conn. characterset: utf8
    UNIX socket: /my/mysql/mariadb/mysql.sock
    Uptime: 23 days 12 hours 23 min 43 sec
    Threads: 11 Questions: 92512 Slow queries: 0 Opens: 359 Flush tables: 1 Open tables: 345 Queries per second avg: 0.045
  2. 創建表和插入數據
    創建表
    CREATE TABLE test (
    name varchar(10) NOT NULL,
    age int(10) DEFAULT NULL,
    address varchar(20) DEFAULT NULL,
    PRIMARY KEY (name)
    )
    插入數據報錯
    mysql> insert into test values(“zhangsan”,18,“上海”);
    ERROR 1366 (HY000): Incorrect string value: ‘\xE4\xB8\x8A\xE6\xB5\xB7’ for column ‘address’ at row 1
    字符集不對,沒有指定字符集使用的是latin1
    mysql> show create table test;
    | test | CREATE TABLE test (
    name varchar(10) NOT NULL,
    age int(10) DEFAULT NULL,
    address varchar(20) DEFAULT NULL,
    PRIMARY KEY (name)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
    修改表的字符集
    alter table test convert to character set utf8;
    現在就可以插入數據了
    mysql> insert into test values(“zhangsan”,18,“上海”);
  3. 執行explain語句
    mysql> explain insert into test values(“zhangsan”,18,“上海”);
    ±—±------------±------±-----------±-----±--------------±-----±--------±-----±-----±---------±------+
    | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
    ±—±------------±------±-----------±-----±--------------±-----±--------±-----±-----±---------±------+
    | 1 | INSERT | test | NULL | ALL | NULL | NULL | NULL | NULL | NULL | NULL | NULL |
    ±—±------------±------±-----------±-----±--------------±-----±--------±-----±-----±---------±------+
    這裏驗證了兩個問題,執行計劃是不會被真的執行,除select語句使用,insert語句也可以使用
    mysql> explain update test set name = “lisi” where name = “zhangsan”;
    ±—±------------±------±-----------±------±--------------±--------±--------±------±-----±---------±------------+
    | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
    ±—±------------±------±-----------±------±--------------±--------±--------±------±-----±---------±------------+
    | 1 | UPDATE | test | NULL | range | PRIMARY | PRIMARY | 32 | const | 1 | 100.00 | Using where |
    ±—±------------±------±-----------±------±--------------±--------±--------±------±-----±---------±------------+
    update語句也可以使用,再次驗證explain不會真的去修改數據庫
    mysql> explain select * from test;
    ±—±------------±------±-----------±-----±--------------±-----±--------±-----±-----±---------±------+
    | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
    ±—±------------±------±-----------±-----±--------------±-----±--------±-----±-----±---------±------+
    | 1 | SIMPLE | test | NULL | ALL | NULL | NULL | NULL | NULL | 1 | 100.00 | NULL |
    ±—±------------±------±-----------±-----±--------------±-----±--------±-----±-----±---------±------+
    mysql> explain delete from test;
    ±—±------------±------±-----------±-----±--------------±-----±--------±-----±-----±---------±------------------+
    | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
    ±—±------------±------±-----------±-----±--------------±-----±--------±-----±-----±---------±------------------+
    | 1 | DELETE | test | NULL | ALL | NULL | NULL | NULL | NULL | 1 | 100.00 | Deleting all rows |
    ±—±------------±------±-----------±-----±--------------±-----±--------±-----±-----±---------±------------------+

explain 返回字段解釋

  1. id
    id 相同執行順序由上至下
    id 不同,id的值越大優先級越高,越先被執行
    id 爲NULL時表示一個結果集,常見爲union中
    例如下面的例子
    mysql> explain select uid from user_qq union select uid from user;
    ±—±-------------±-----------±-----------±------±--------------±-------------±--------±-----±-----±---------±----------------+
    | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
    ±—±-------------±-----------±-----------±------±--------------±-------------±--------±-----±-----±---------±----------------+
    | 1 | PRIMARY | user_qq | NULL | index | NULL | uniq_user_id | 9 | NULL | 6 | 100.00 | Using index |
    | 2 | UNION | user | NULL | index | NULL | name | 82 | NULL | 11 | 100.00 | Using index |
    | NULL | UNION RESULT | <union1,2> | NULL | ALL | NULL | NULL | NULL | NULL | NULL | NULL | Using temporary |
    ±—±-------------±-----------±-----------±------±--------------±-------------±--------±-----±-----±---------±----------------+
  2. select_type
    由於往往關心的是查詢的效率,而explain也是將select這一大類分成了很多種情況
    1. SIMPLE 簡單查詢(不使用UNION或子查詢)
      例如 explain select * from test;
    2. PRIMARY 最外層的SELECT語句
    3. DEPENDENT SUBQUERY 依賴的子查詢
      mysql> explain select u.*, (select q.openid from user_qq q where u.uid = q.uid) from user u;
      ±—±-------------------±------±-----------±-----±--------------±-------------±--------±----------±-----±---------±------+
      | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
      ±—±-------------------±------±-----------±-----±--------------±-------------±--------±----------±-----±---------±------+
      | 1 | PRIMARY | u | NULL | ALL | NULL | NULL | NULL | NULL | 11 | 100.00 | NULL |
      | 2 | DEPENDENT SUBQUERY | q | NULL | ref | uniq_user_id | uniq_user_id | 9 | him.u.uid | 1 | 100.00 | NULL |
      ±—±-------------------±------±-----------±-----±--------------±-------------±--------±----------±-----±---------±------+
    4. SUBQUERY 子查詢(沒有依賴的子查詢)
      explain select u.*, (select q.openid from user_qq q where q.uid =1) from user u;
    5. UNION 聯合查詢,UNION後的查詢
    6. UNION RESULT 聯合查詢的結果
      mysql> explain select uid from user union select uid from user_qq;
      ±—±-------------±-----------±-----------±------±--------------±-------------±--------±-----±-----±---------±----------------+
      | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
      ±—±-------------±-----------±-----------±------±--------------±-------------±--------±-----±-----±---------±----------------+
      | 1 | PRIMARY | user | NULL | index | NULL | name | 82 | NULL | 11 | 100.00 | Using index |
      | 2 | UNION | user_qq | NULL | index | NULL | uniq_user_id | 9 | NULL | 6 | 100.00 | Using index |
      | NULL | UNION RESULT | <union1,2> | NULL | ALL | NULL | NULL | NULL | NULL | NULL | NULL | Using temporary |
      ±—±-------------±-----------±-----------±------±--------------±-------------±--------±-----±-----±---------±----------------+
  3. table 即表的名稱,若有別名的則顯示別名
  4. partitions 表分區,物理存儲文件可以分幾個文件存儲,一張表分幾個文件來存儲
  5. type 訪問類型
    system > const > eq_ref > ref > range > index > ALL 查詢效率依次降低(實際並非嚴格)
    system 數據庫引擎爲MyISAM 且只有一條數據
    const 命中主鍵或者唯一索引,且查詢條件爲常量且要命中
    eq_ref join查詢中關聯的是主鍵或聯合索引例如explain select * from user left join user_qq on user.uid = user_qq.uid;
    ref 與const的區別就是這裏是普通索引,可能出現重複數據
    range 在索引字段上使用 > ,in,bettwen 等範圍查詢條件
    index select中的字段爲索引字段
    all 全表掃描
  6. possible_keys 可能使用到的索引
  7. key 使用到的索引
  8. key_len 索引的長度
  9. ref 連接匹配條件
  10. rows 返回估算的結果集數目,並不是一個準確的值。
  11. filtered 這個字段表示存儲引擎返回的數據在server層過濾後,剩下多少滿足查詢的記錄數量的比例,注意是百分比,不是具體記錄數
  12. extra 額外信息
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章