MySQL Explain關鍵字與索引優化建議

2022-08-16 09:06:12 字數 3905 閱讀 2788

用到的資料表如下:

drop table if exists `actor`;

create table `actor` (

`id` int(11) not null,

`name` varchar(45) default null,

`update_time` datetime default null,

primary key (`id`)

) engine=innodb default charset=utf8;

insert into `actor` (`id`, `name`, `update_time`) values (1,'a','2017-12-22 15:27:18'), (2,'b','2017-12-22 15:27:18'), (3,'c','2017-12-22 15:27:18');

drop table if exists `film`;

create table `film` (

`id` int(11) not null auto_increment,

`name` varchar(10) default null,

primary key (`id`),

key `idx_name` (`name`)

) engine=innodb default charset=utf8;

insert into `film` (`id`, `name`) values (3,'film0'),(1,'film1'),(2,'film2');

drop table if exists `film_actor`;

create table `film_actor` (

`id` int(11) not null,

`film_id` int(11) not null,

`actor_id` int(11) not null,

`remark` varchar(255) default null,

primary key (`id`),

key `idx_film_actor_id` (`film_id`,`actor_id`)

) engine=innodb default charset=utf8;

insert into `film_actor` (`id`, `film_id`, `actor_id`) values (1,1,1),(2,1,2),(3,2,1);

結構:

加粗字段表示加了索引,下劃線表示聯合索引

表示 select的序列號,有幾個select就有幾個id。

例子:

select_type 表示對應行是簡單還是複雜的查詢

這一列表示 explain 的一行正在訪問哪個表

這一列表示關聯型別或訪問型別,即mysql決定如何查詢表中的行,查詢資料行記錄的大概範圍

從最優到最差為:system>const>eq_ref>ref>range>index>all一般來說,得保證查詢達到range級別,最好達到refnull:

mysql能夠在優化階段分解查詢語句,在執行階段用不著在訪問表或索引。

例如:在索引列中選取最小值,可以單獨查詢索引來完成,不需要在執行時訪問表。

mysql能對查詢的某部分進行優化,並將其轉化成乙個常量(可以看成 show warnings 的結果)。用於 primary key 或 unique key 的所有類與常數比較時,所以表最多有乙個匹配行,讀取1次,速度比較快。system是const的特例,表裡只有一條元素時為system

eq_ref:

primary key 或 unique key 索引的所在部分被join連線使用 ,最多隻會返回一條符合條件的記錄。這可能是在 const 之外最好的聯接型別了,簡單的 select 查詢不會出現這種 type。

ref:

相比 eq_ref,不使用唯一索引,而是使用普通索引或者唯一性索引的部分字首,索引要和某個值相比較,可能會找到多個符合條件的行

range:

範圍掃瞄通常出現在*in(), between ,> ,=*等操作中。使用乙個索引來檢索給定範圍的行。

index:

掃瞄全表索引,這通常比all快一些。(index是從索引中讀取的,而all是從硬碟中讀取)

all:

即全表掃瞄,意味著mysql需要從頭到尾去查詢所需要的行。通常情況下這需要增加索引來進行優化了

這一列顯示查詢可能使用哪些索引來查詢。

explain 時可能出現 possible_keys 有列,而 key 顯示 null 的情況,這種情況是因為表中資料不多,mysql認為索引對此查詢幫助不大,選擇了全表查詢。

如果該列是null,則沒有相關的索引。在這種情況下,可以通過檢查 where 子句看是否可以創造乙個適當的索引來提高查詢效能,然後用 explain 檢視效果。

這一列顯示mysql實際採用哪個索引來優化對該錶的訪問。

如果沒有使用索引,則該列是 null。如果想強制mysql使用或忽視possible_keys列中的索引,在查詢中使用 force index、ignore index。

這一列顯示了mysql在索引裡使用的位元組數,通過這個值可以算出具體使用了索引中的哪些列。

舉例來說,film_actor的聯合索引idx_film_actor_idfilm_idactor_id兩個 int 列組成,並且每個 int 是4位元組。通過結果中的key_len=4可推斷出查詢只使用了第乙個列film_id列來執行索引查詢。

key_len計算規則如下:數值型別

時間型別 

如果字段允許為 null,需要1位元組記錄是否為 null

索引最大長度是768位元組,當字串過長時,mysql會做乙個類似左字首索引的處理,將前半部分的字元提取出來做索引

這一列顯示了在key列記錄的索引中,表查詢值所用到的列或常量,

常見的有:const(常量),欄位名(例:film.id)

這一列是mysql估計要讀取並檢測的行數,注意這個不是結果集裡的行數

這一列展示的是額外資訊。常見的重要值如下:

關於mysql explain關鍵字的詳解

1 id列數字越大越先執行,如果說數字一樣大,那麼就從上往下依次執行,id列為null的就表是這是乙個結果集,不需要使用它來進行查詢。2 select type列常見的有 a 表示不需要union操作或者不包含子查詢的簡單select查詢。有連線查詢時,外層的查詢為 且只有乙個 b primary ...

new關鍵字 this關鍵字 base關鍵字

使用new,所做的三件事 1.類是引用物件,引用物件是在堆中開闢空間 在堆中開闢空間 2.在開闢的堆空間中建立物件 3.呼叫物件的構建函式 4.隱藏父類成員 子類的成員可以與隱藏從父類繼承的成員,類似於重寫。public new void sayhello this關鍵字的使用 1.代表當前類的物件...

this關鍵字 static關鍵字

1.當成員變數和區域性變數重名,可以用關鍵字this來區分 this 代表物件,代表那個物件呢?當前物件 this就是所在函式所屬物件的引用 簡單說 那個物件呼叫了this所在的函式,this就代表哪個物件 this也可以用於在建構函式中呼叫其他建構函式 注意 只能定義在建構函式的第一行,因為初始化...