天天看點

MySQL使用索引的典型場景

作者:貴哥說Java創業

以下案例表用的是MySQL官網的案例庫sakila。

比對全值

對索引中所有列都指定具體值,即是對索引中的所有列都有等值比對的條件。

例如,租賃表 rental 中通過指定出租日期 rental_date + 庫存編inventory id+ 客戶編号customer id 的組合條件進行查詢,從執行計劃的 key和extra 兩字值看到優化器選擇了複合索引idx rental date:

EXPLAIN SELECT * from rental where rental_date='2005-05-25 17:22:10' and inventory_id=373 and customer_id=343;

           
MySQL使用索引的典型場景

比對值的範圍查詢

對索引的值進行範圍查找。

例如,檢索租賃表rental中客戶編号customer_id在指定範圍的記錄:

EXPLAIN SELECT * from rental where  customer_id >=373 and customer_id < 400

           
MySQL使用索引的典型場景

類型 ype 為 range 說明優化器選擇範圍查詢,索引 key 為 idx_fk_customer_id 說明優化器選擇索引 idx_fk_customer_id 來加速通路,注意到這個例子中 Extra列為 Using index condition,表示MySQL使用了ICP來進一步優化查詢,在檢索的時候,把條件customer_id的過濾操作下推到存儲引擎層來完成,這樣能夠降低不必要的IO通路。

比對最左字首

僅僅使用索引中的最左邊列進行香找,比如在c0l1 +col2 +col3 字段上的聯合索引能夠被包含 col1、(col1 + col2)、(col1 +col2 + col3)的值查詢利用到,可是不能夠被 col2、(col2 + col3)的等值查詢利用到;

以支付表 payment為例,如果查詢條件中僅包含索引的第一列支付日期 payment date 和索引的第三列更新時間update 的時候,從執行計劃的 key 和 extra 看到優化器仍然能夠使用複合索idx_payment_date進行條件過濾:

alter table payment add INDEX idx_payment_date(payment_date,amount,last_update);
EXPLAIN SELECT * from payment where payment_date='2006-02-14 15:16:03' and last_update='2006-02-15 22:12:32'

           

但是,如果僅僅選擇符合索引idx_payment_date的第二列支付金額amount和第三列更新時間last_update進行查詢時,那麼執行計劃顯示并不會利用到索引idx_payment_date:

EXPLAIN SELECT * from payment where amount=3.98 and last_update='2006-02-15 22:12:32'

           
MySQL使用索引的典型場景

覆寫索引

僅僅對索引進行查詢,當查詢的列都在索引的字段中時,查詢的效率更高;

EXPLAIN SELECT last_update from payment where payment_date='2006-02-15 22:12:32' and  amount=3.98            
MySQL使用索引的典型場景

Extra部分變成Using index,意味着,現在直接通路索引就足夠擷取到所需要的資料,不需要通過索引回表查詢。

比對列字首

僅僅使用索引列中的第一列,并且隻包含索引第一列的開頭一部分進行查找。

例如,現在需要查詢出标題title是以AFRICAN開頭的電影資訊,從執行計劃能夠清楚看到,idx_title_desc_part索引被利用上了:

create index idx_title_desc_part on film_text(title(10),description(20));

EXPLAIN SELECT title from film_text where title like 'AFRICAN%'

           
MySQL使用索引的典型場景

​Extra值為Using where表示優化器需要通過索引回表查詢資料。

索引比對部分精确而其他部分進行範圍比對

例如,需要查詢出租日期 renlal date 為指定日期且客戶編号 customer id為指定範圍的庫存:

EXPLAIN  select inventory_id from rental where rental_date='2006-02-14 15:16:03' and customer_id >= 300 and customer_id <= 400

           
MySQL使用索引的典型場景

類型 type為 range 說明優化器選擇範圍查詢,索引key 為 idx_rental_date 說明優化器選擇索引idx_rental_date 幫助加速查詢,同時由于隻查詢索引字段 inventory_id 的值,是以在 Extrs郭分能看到 Using ndex,表示查詢使用了覆寫索引掃描。

column name is null

如果列名是索引,那麼使用column_name is null 就會使用索引。

EXPLAIN SELECT * from payment where rental_id is null 
           
MySQL使用索引的典型場景

繼續閱讀