嗯??聽到這個問題的時候,是不是有些茫然?
我連什么是索引都不是很清晰明了,你給我講什么建立索引的時機?!!!
是的,很多同學只是有所耳聞,並且可能就是只知道索引可以優化sql效率,但是至於其所以然並不清晰。那么我們現在先談談什么是索引。
對於MySQL而言,官方對索引給出的定義是:索引(index)是幫助MySQL高效獲取數據的數據結構。
這個時候,我們可以了解到索引就是一種數據結構。
也可以通俗的理解:一種排好序等你來直接查詢的快速查找的數據結構。所以上面也說道了可以優化sql的查詢效率。
那么索引到底如何實現的呢?這里我們簡單的說一下:
用mysql舉例來說明,mysql支持多種存儲引擎,那么各種存儲引擎支持的索引也是不一樣的。這里我們說到的mysql就支持多種:日報B-、B+Tree;hash;全文。
這里我們重點說一下:聚簇索引和非聚簇索引。(很多場景經常問)
在mysql的存儲引擎中:MyISAM和innodb,其中分別實現的是非聚簇索引和聚簇索引。
對於兩種索引結構來說:
聚簇索引:聚餐索引就是數據的物理存儲順序,通俗的講,就是排隊,比如一排人坐在位置上,我要他們全起立,按照你們個個座位的序號,給我排好隊。這樣,我叫第三個人出列,就可以直接找到了。
非聚簇索引:索引順序與數據物理排序順序無關。通俗的講,就是你們雖然按序號坐着,但是我手上有一份名單,這名單的順序是按照姓名的A-Z排序的。那么我叫第三個人出列,就可以直接看到這個人的唯一姓名了。
那么對於上面兩種存儲引擎,適用於什么場景呢。通常來說,非聚簇索引適合大量的讀操作。聚簇索引適用於大量的增刪改操作。
好,簡單的索引拓展結束,我們重點說說使用索引。
建立索引的好處
那么建立索引有什么好處嗎?這么講,我們在圖書館找書的時候,是不是按照書標簽去找書的,這樣,即使在幾百萬的藏書中,我們也能找到自己要的書籍。這樣在系統層面,我們降低了數據庫的IO操作。通過索引,我們也不需要排序,直接就降低了排序的性能消耗。
那么壞處呢?
那么萬物皆有雙面性,在我們建立索引的同時,也就是說,我們還要對索引進行維護,也就是說,需要維護兩套數據。且在對比哦庫表進行增刪改操作的時候,還需要對索引進行一個更新信息操作。從底層實現來說,索引也是一張庫表,其中的數據內容就是表結構對應的索引字段,所以說索引也消耗了一定的存儲空間。類似一種觸發器機制。
那么說其弊端也顯而易見了,就是維護的成本,和io讀寫。
總結來說,就是索引適合在高頻的讀操作中建立,且不適合高頻的增刪改操作。
那么最后面我們可以直接對索引進行一個使用的總結了。
在哪些場景適合使用索引呢?
1.在我們建立表的時候,其實默認已經將主鍵上建立唯一索引了。
2.當某個字段頻繁的作為查詢參數,查詢條件的字段也建議使用,比如號碼,唯一,且查詢頻率高
3.當我使用join進行一個鏈表查詢,就適合使用,這樣,外鍵也是一種查詢條件頻率高。
4.排序的字段,當我們對一些數據量較大的表進行一個查詢且排序,例如日志表,都會使用到創建時間作為排序字段,並且來說,這些表的數據量都不小,這個時候,我們建立索引會有明顯的效率提升。
5.還有我們做統計數據的時候,通常會對該字段進行一種數據的匯總統計,在分組查詢的時候也是一樣的意思,這個時候,也建議建立索引。
注:在建立索引的時候,組合索引建立比單個更有效果,但是不能貪多哦。
那么也有一些場景不建議使用索引:
1.表記錄較少,你一共就10條數據,我還建立一個索引?可能索引的數據存儲都比實際數據都多。
2.還有一種就是上面已經說到的,高頻的增刪改表。比如流水表,秒級的增加數據。這種表結構,我們通常不建議。
3.查詢條件幾乎用不到的字段。這個自己理解。
4.還有就是那種,你選擇他作為查詢條件,但是幾乎沒有條件過濾的感覺的字段。例如,性別,你說你查詢男和女有多大的過濾??
那么后面,我們肯定得講講存儲引擎中的B樹,這個可是高頻面試題。