1. 程式人生 > 其它 >MySQL資料庫——索引

MySQL資料庫——索引

如果SQL查詢比較慢,就會要給欄位加索引。索引就像書的目錄,可以提高查詢效率。

實現索引的方式很多,常見的索引模型有雜湊表、有序陣列、搜尋樹。

雜湊表這種結構適用於只有等值查詢的場景,比如Memcached以及其他一些NoSQL,不適用範圍查詢。

有序陣列在等值查詢(二分法)和範圍查詢(二分法先找左)都非常優秀,但是更新資料麻煩得很,所以只適用於靜態儲存引擎。

二叉搜尋樹BST,等值查詢是O(logN),更新也是,但是要是平衡二叉樹。

二叉搜尋樹效率高,但是實際卻不使用,因為耗空間。索引不僅存在記憶體中,還要寫到磁盤裡面。樹高有多少,就要訪問多少次磁碟。為了訪問儘量少的資料塊,因此決定用N叉樹替換。N叉樹在讀寫上有效能優點,同時也適配磁碟的訪問模式。跳錶、LSM樹等資料結構也被用於引擎設計。

關於InnoDB的索引模型。在InnoDB中,表都是根據主鍵順序以索引形式存放,這種儲存方式的表稱為索引組織表。使用B+樹。

可以根據葉子節點的內容,索引型別分為主鍵索引和非主鍵索引。

主鍵索引的葉子節點存整行資料,也叫聚簇索引。比如select * from T where ID=500;只需搜尋ID這棵B+樹。

非主鍵索引的葉子節點存主鍵的值,也叫二級索引。比如select * from T where k=5;需要先搜尋k索引樹,得到ID的值為500,再到ID索引樹搜尋一次。這個過程被叫做回表。

回表很麻煩的。比如執行select * from T where k between 3 and 5,在下面的結構中,需要執行幾次樹的搜尋操作,會掃描多少行?

 

 過程:首先在k索引樹找到k=3取得ID=300,再去ID索引樹查到R3。接下來k=5,k=6。由於查詢結果所需要的資料只在主鍵索引上,所以不得不回表。可不可以經過索引優化,避免回表過程?答案就是覆蓋索引。覆蓋索引其實就是聯合索引。由於覆蓋索引可以減少樹的搜尋次數,顯著提升查詢效能,所以使用覆蓋索引是一個常用的效能優化手段。

比如在市民資訊表上,將身份證號和名字建立聯合索引。現在有一個高頻請求,根據市民的身份證號查詢他的名字,這個聯合索引就有意義了。它可以在這個高頻請求上用到覆蓋索引,不需要回表查詢整行記錄,減少語句的執行時間。

B+樹這種索引結構,可以利用索引的最左字首來定位記錄。最左字首可以是聯合索引的最左N個欄位,也可以是字串索引的最左M個字元。

為了維護B+樹的索引有序性,需要做索引維護。當插入的時候,資料頁滿了,就要新申請頁,然後挪動部分資料過去,就是頁分裂,也影響資料頁的利用率。當刪除的時候,利用率很低之後,就要將資料頁做合併。

哪些場景下應該使用自增主鍵,哪些場景下不應該。自增主鍵是指自增列上定義的主鍵。AUTO_INCREMENT。