1. 程式人生 > 資料庫 >mysql索引覆蓋例項分析

mysql索引覆蓋例項分析

本文例項講述了mysql索引覆蓋。分享給大家供大家參考,具體如下:

索引覆蓋

如果查詢的列恰好是索引的一部分,那麼查詢只需要在索引檔案上進行,不需要回行到磁碟再找資料。這種查詢速度非常快,稱為“索引覆蓋”。

假設有一張t15表,在表中建立了一個聯合索引:cp(cat_id,price)

這裡寫圖片描述

當我們使用下面的sql語句,會出現索引覆蓋的情況。不信我們可以來檢視一下,這裡的Extra中顯示了Using index,表示這條sql語句剛好用到了索引覆蓋。

這裡寫圖片描述

select price from t15 where cat_id = 1;

在來看一題,建立一張t11表,在email列有一個索引

這裡寫圖片描述

假設我們用這樣的查詢語句:

select eamil from  t11 where right(email,4)='.com'

查詢分析:

這裡寫圖片描述

首先看一下Extra,這裡有Using index,說明這裡使用到了索引覆蓋,而possible_keys為NULL的原因是因為,使用到了mysql中的函式,所以在查詢的時候並沒有使用到email索引,但是key卻為email,表示了使用到了索引進行排序,不信我把資料列印看看。

這裡寫圖片描述

這裡的資料是經過排序的。原本的資料是這樣的。

這裡寫圖片描述

索引覆蓋的問題

create table A (
id varchar(64) primary key,ver int,…
)

表中有幾個很長的欄位varbinary(3000) ,在id、ver上有聯合索引 ,共10000條資料

為什麼select id from A order by id特別慢?
select id from A order by id,ver非常快

疑問: id,(id,ver)都有索引,select id 應該都產生”索引覆蓋”的效果,為什麼前者慢,而後快?

思路:innodb聚簇與myisam索引的不同,索引覆蓋 這2個角度來考慮

(1)假設此表使用的是Myisam的索引,那麼這兩條sql語句都不需要回行查詢資料,那麼他們的速度應該差不多。

(2)假設此表使用的是InnoDB的索引,那麼select id from A order by id這句sql使用到了主鍵索引,因為InnoDB的每個主鍵都掛載這每行的資料,並且本題中還有幾個特別大的欄位,所以會在查詢id的時候需要走的相對慢;而select id from A order by id,ver這句sql使用到了id,ver聯合索引,在InnoDB儲存引擎中,次索引儲存的是對主鍵索引的應用,所以次索引不掛載該行的資料,那麼在(id,ver)索引中查詢id會快,當找到對應的節點樹時,只需要再次查詢到主鍵索引的位置,即可拿到該行的資料,這樣比較快。

推斷:

(1)表如果是myisam引擎,2個語句,速度不會有明顯差異.
(2)innodb表因為聚簇索引,id索引要在磁碟上跨N多塊,導致速度慢.
(3)即使innodb引擎,如果沒有那幾個varbinay長列,2個語句的速度也不會有明顯差異.

t12表,儲存引擎為MyISAM,有主鍵索引和(id,ver)符合索引,還有幾個大的變長欄位,測試推論1

這裡寫圖片描述

t13表,儲存引擎為InnoDB,有主鍵索引和(id,ver)符合索引,還有幾個大的變長欄位推論2

這裡寫圖片描述

t14表,儲存引擎為InnoDB,有主鍵索引和(id,ver)符合索引,沒有幾個大的變長欄位推論3

這裡寫圖片描述

t12,t13,t14每張表中都有1W條資料,然後進行測試,測試結果如下,我們的推論是正確的。

這裡寫圖片描述

更多關於MySQL相關內容感興趣的讀者可檢視本站專題:《MySQL索引操作技巧彙總》、《MySQL常用函式大彙總》、《MySQL日誌操作技巧大全》、《MySQL事務操作技巧彙總》、《MySQL儲存過程技巧大全》及《MySQL資料庫鎖相關技巧彙總》

希望本文所述對大家MySQL資料庫計有所幫助。