mysql執行計劃分析

create table test1(a int,b tinyint,c varchar(20),d int);
alter table test1 add primary key (a); --添加主鍵
alter table test1 drop primary key; --刪除主鍵
alter table test1 add unique key (b,c); -- 添加唯一索引
alter table test2 drop key c_2; --刪除索引
insert into test1 values(1,2,"333",22);
insert into test1 values(2,21,"333",22),(3,20,"333",22),(4,25,"333",22);
-- 最終表如下
Create Table: CREATE TABLE `test1` (
  `a` int(11) NOT NULL DEFAULT '0',
  `b` tinyint(4) DEFAULT NULL,
  `c` varchar(20) DEFAULT NULL,
  `d` int(11) DEFAULT NULL,
  PRIMARY KEY (`a`),
  UNIQUE KEY `b` (`b`,`c`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
  • explain select a from test1 where b>10\G;:使用到覆蓋索引(輔助索引的葉子節點上是主鍵),在索引上進行了範圍查詢
    在這裏插入圖片描述

  • explain select a from test1 where b>10 and c="ff"\G;使用到覆蓋索引(輔助索引的葉子節點上是主鍵),在索引上進行了範圍查詢
    在這裏插入圖片描述

  • explain select d from test1 where b>10\G; 這裏雖然有可用的索引,但是mysql並沒有用,因爲需要d字段同時選擇度太低,所以肯定需要到聚集索引上二次查詢,權衡下mysql決定直接掃描表
    在這裏插入圖片描述

  • explain select d from test1 where b>24\G;: 使用索引進行掃描,相對全表掃描代價較小,具體可以使用optimizer_trace分析
    在這裏插入圖片描述

  • explain select d from test1 where a>10\G;:使用到了聚集索引(主鍵)進行範圍查詢
    在這裏插入圖片描述

聯合索引

create table test2 (a int auto_increment primary key, b int, c int ,d int ,e int,index(b,c,d));
insert into test2(b,c,d,e) values (1,2,3,4),(2,1,4,5),(2,3,4,5),(1,2,3,2),(3,4,2,1);
-- 換句話說建立了bcda索引。
  • explain select d from test2 where b=1 order by db=1用到了索引,但是排序沒有,排序使用了文件
    在這裏插入圖片描述

  • explain select d from test2 where b>1 order by d;:索引覆蓋、用文件進行排序
    在這裏插入圖片描述

  • explain select d from test2 where b>1 order by c; 排序沒有用到索引,所以採用臨時文件進行排序Using filesort
    在這裏插入圖片描述

  • explain select d from test2 where b=1 order by c\G;:排序和查找都用到了索引
    在這裏插入圖片描述

  • explain select d from test2 where c=1 order by b;: 排序和查找都用到了索引,不過相對上面的效率較低。這裏利用了索引覆蓋
    在這裏插入圖片描述

  • explain select * from test2 where c=3 order by b;: 這條和上一條差別就是取的字段不同,上面使用了索引覆蓋,但是這條需要到聚集索引上二次查詢,所以mysql選擇直接掃描表
    在這裏插入圖片描述

  • select * from test2 where b=3 order by d; : 搜索b用到了索引,但是回聚集索引上進行了查詢,同時使用臨時文件進行了排序
    在這裏插入圖片描述

  • 結論:在聯合索引裏需要滿足最左原則,索引爲(bcda);如果字段不連續只能使用一部分索引eg:(b=0 and d=10);字段中有範圍查詢也只能用一部分索引(b>0 and c=0)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章