Mysql聚簇索引 二級索引 輔助索引


Mysql聚簇索引 二級索引 輔助索引

索引就像是書的目錄,是與表或視圖關聯的磁盤上結構,可以加快從表或視圖中檢索行的速度。索引中包含由表或視圖中的一列或多列生成的鍵。這些鍵存儲在一個結構(BTree)中,使SQL可以快速有效地查找與鍵值關聯的行。

為什么要建索引,即索引的優點

  1. 沒有索引則檢索過程變成了順序查找,O(n)的時間復雜度幾乎是不能忍受的。
  2. 建立索引的列可以保證行的唯一性,生成唯一的rowId
  3. 建立索引可以有效縮短數據的檢索時間
  4. 建立索引可以加快表與表之間的連接
  5. 為用來排序或者是分組的字段添加索引可以加快分組和排序順序

索引的缺點

  1. 創建索引和維護索引需要時間成本,這個成本隨着數據量的增加而加大
  2. 創建索引和維護索引需要空間成本,每一條索引都要占據數據庫的物理存儲空間,數據量越大,占用空間也越大(數據表占據的是數據庫的數據空間)
  3. 降低表的增刪改的效率,因為每次增刪改索引需要進行動態維護,導致時間變長

什么樣的表和列要建立索引

①  總的來說就是數據量大的,經常進行查詢操作的表要建立索引

②  表中字段建立索引應該遵循幾個原則:

  1)   越小的數據類型通常更好:越小的數據類型通常在磁盤、內存中都需要更少的空間,處理起來更快。

  2)   簡單的數據類型更好:整型數據比起字符,處理開銷更小,因為字符串的比較更復雜,處理起來也更耗時。

  3)   盡量避免NULL:應該指定列為NOT NULL。含有空值的列很難進行查詢優化,因為它們使得索引、索引的統計信息以及比較運算更加復雜。你應該用0、一個特殊的值或者一個空串代替空值。

  4)   對非唯一的字段,例如“性別”這種大量重復值的字段,增加索引也沒有什么意義,所以索引的建立應當更多的選取唯一性更高的字段

③  表與表連接用於多表聯合查詢的約束條件的字段應當建立索引

④  用於排序的字段可以添加索引,用於分組的字段應當視情況看是否需要添加索引。

⑤  添加多列索引的時候,對應的多條件查詢可以觸發該索引的同時,索引最左側的列的單條件查詢也可以觸發

⑥  如果有些表注定只會進行查詢所有,也就沒必要添加索引,因為查詢全部只能進行全量搜索即掃描全表。

 

聚簇索引和非聚簇索引

MySQL普遍使用B+Tree實現其索引結構。

mysql中每個表都有一個聚簇索引(clustered index ),除此之外的表上的每個非聚簇索引都是二級索引,又叫輔助索引(secondary indexes)。

當數據庫一條記錄里包含多個字段時,一棵B+樹就只能存儲主鍵,如果檢索的是非主鍵字段,則主鍵索引失去作用,又變成順序查找了。這時應該在第二個要檢索的列上建立第二套索引。  這個索引由獨立的B+樹來組織。有兩種常見的方法可以解決多個B+樹訪問同一套表數據的問題,一種叫做聚簇索引(clustered index ),一種叫做非聚簇索引(secondary index)。這兩個名字雖然都叫做索引,但這並不是一種單獨的索引類型,而是一種數據存儲方式。對於聚簇索引存儲來說,行數據和主鍵B+樹存儲在一起,輔助鍵B+樹只存儲輔助鍵和主鍵,主鍵和非主鍵B+樹幾乎是兩種類型的樹。對於非聚簇索引存儲來說,主鍵B+樹在葉子節點存儲指向真正數據行的指針,而非主鍵。

聚簇索引並不是一種單獨的索引類型,而是一種數據存儲方式。具體的細節依賴於其實現方式,但InnoDB的聚簇索引實際上在同一個結構中保存了B-Tree索引和數據行。

當表有聚簇索引時,他的數據行實際上存放在索引的葉子頁(leaf page)中。術語 “聚簇”表示數據行和相鄰的鍵值緊湊地存儲在一起(這並非總成立)。

因為無法同時把數據行存放在兩個不同的地方,索引一個表只能有一個聚簇索引。

 

注:葉子頁面包含完整的元組,而內節點頁面僅包含索引的列(索引的列為整型)。一些DBMS允許用戶指定聚簇索引,但是MySQL的存儲引擎到目前為止都不支持。InnoDB對主鍵建立聚簇索引。如果你不指定主鍵,InnoDB會用一個具有唯一且非空值的索引來代替。如果不存在這樣的索引,InnoDB會定義一個隱藏的主鍵,然后對其建立聚簇索引。一般來說,DBMS都會以聚簇索引的形式來存儲實際的數據,它是其它二級索引的基礎。

 innodb MyISAM

以InnoDB來說,每個InnoDB表具有一個特殊的索引稱為聚集索引。如果您的表上定義有主鍵,該主鍵索引是聚集索引。如果你不定義為您的表的主鍵時,MySQL取第一個唯一索引(unique)而且只含非空列(NOT NULL)作為主鍵,InnoDB使用它作為聚集索引。如果沒有這樣的列,InnoDB就自己產生一個這樣的ID值,它有六個字節,而且是隱藏的,使其作為聚簇索引。

InnoDB使用的是聚簇索引,將主鍵組織到一棵B+樹中,而行數據就儲存在葉子節點上,若使用"where id = 14"這樣的條件查找主鍵,則按照B+樹的檢索算法即可查找到對應的葉節點,之后獲得行數據。若對Name列進行條件搜索,則需要兩個步驟:第一步在輔助索引B+樹中檢索Name,到達其葉子節點獲取對應的主鍵。第二步使用主鍵在主索引B+樹種再執行一次B+樹檢索操作,最終到達葉子節點即可獲取整行數據。

 MyISM使用的是非聚簇索引,非聚簇索引的兩棵B+樹看上去沒什么不同,節點的結構完全一致只是存儲的內容不同而已,主鍵索引B+樹的節點存儲了主鍵,輔助鍵索引B+樹存儲了輔助鍵。表數據存儲在獨立的地方,這兩顆B+樹的葉子節點都使用一個地址指向真正的表數據,對於表數據來說,這兩個鍵沒有任何差別。由於索引樹是獨立的,通過輔助鍵檢索無需訪問主鍵的索引樹。

  為了更形象說明這兩種索引的區別,我們假想一個表如下圖存儲了4行數據。其中Id作為主索引,Name作為輔助索引。圖示清晰的顯示了聚簇索引和非聚簇索引的差異。

 

  我們重點關注聚簇索引,看上去聚簇索引的效率明顯要低於非聚簇索引,因為每次使用輔助索引檢索都要經過兩次B+樹查找,這不是多此一舉嗎?聚簇索引的優勢在哪?

  1 由於行數據和葉子節點存儲在一起,這樣主鍵和行數據是一起被載入內存的,找到葉子節點就可以立刻將行數據返回了,如果按照主鍵Id來組織數據,獲得數據更快。

  2 輔助索引使用主鍵作為"指針" 而不是使用地址值作為指針的好處是,減少了當出現行移動或者數據頁分裂時輔助索引的維護工作,使用主鍵值當作指針會讓輔助索引占用更多的空間,換來的好處是InnoDB在移動行時無須更新輔助索引中的這個"指針"。也就是說行的位置(實現中通過16K的Page來定位,后面會涉及)會隨着數據庫里數據的修改而發生變化(前面的B+樹節點分裂以及Page的分裂),使用聚簇索引就可以保證不管這個主鍵B+樹的節點如何變化,輔助索引樹都不受影響。

 

 

參考文章:

https://www.cnblogs.com/wajika/p/6682460.html

https://www.cnblogs.com/williamjie/p/11081081.html

https://www.cnblogs.com/ytc6/p/9370962.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM