聚簇索引並不是一種單獨的索引型別,而是一種資料儲存方式.比較常用的就是 innodb 中的聚簇索引,它實際上是在同一結構中儲存了 b-tree 索引和資料行.也就是說乙個表的資料實際存放在索引的葉子頁中.
mysql(innodb)中的聚簇索引不能指定,只能 mysql 自動生成.innodb 中一般是通過主鍵聚集資料.(而在 oracle 中則是需要手動建立)
在 innodb 中如果沒有定義主鍵,會選擇乙個唯一的非空索引來代替,如果沒有這樣的索引,innodb 會隱式定義個主鍵來作為聚簇索引.
innodb 只聚集在乙個頁面中的記錄,包含相鄰鍵值的頁面可能會相距很遠.(這句話什麼意思?)由於儲存介質的特性,磁碟本身訪問就比主存慢很多,再加上機械運動耗費,磁碟的訪問速度往往是主存的幾百分分之一,因此為了提高效率,要儘量減少磁碟i/o。為了達到這個目的,磁碟往往不是嚴格按需讀取,而是每次都會預讀,即使只需要乙個位元組,磁碟也會從這個位置開始,順序向後讀取一定長度的資料放入記憶體。這樣做的理論依據是電腦科學中著名的區域性性原理:
當乙個資料被用到時,其附近的資料也通常會馬上被使用。
程式執行期間所需要的資料通常比較集中。
由於磁碟順序讀取的效率很高(不需要尋道時間,只需很少的旋轉時間),因此對於具有區域性性的程式來說,預讀可以提高i/o效率。
預讀的長度一般為頁(page)的整倍數。頁是計算機管理儲存器的邏輯塊,硬體及作業系統往往將主存和磁碟儲存區分割為連續的大小相等的塊,每個儲存塊稱為一頁(在許多作業系統中,頁得大小通常為4k),主存和磁碟以頁為單位交換資料。當程式要讀取的資料不在主存中時,會觸發乙個缺頁異常,此時系統會向磁碟發出讀盤訊號,磁碟會找到資料的起始位置並向後連續讀取一頁或幾頁載入記憶體中,然後異常返回,程式繼續執行。
一般使用磁碟i/o次數評價索引結構的優劣。先從b+tree分析,根據b+tree的定義,可知檢索一次最多需要訪問h個節點。資料庫系統的設計者巧妙利用了磁碟預讀原理,將乙個節點的大小設為等於乙個頁,這樣每個節點只需要一次i/o就可以完全載入。為了達到這個目的,在實際實現b+tree還需要使用如下技巧:
每次新建節點時,直接申請乙個頁的空間,這樣就保證乙個節點物理上也儲存在乙個頁裡,加之計算機儲存分配都是按頁對齊的,就實現了乙個node只需一次i/o。
我的理解:這裡所說的"頁面"應該是指的"葉子頁",因為 innodb 的每乙個葉子頁佔的空間是指定的(我現在看的這本書上所寫為16k,這又和上面那篇文章說所說的乙個節點的大小和乙個邏輯塊的大小應該相等,為4k又矛盾了,不管怎樣,有頁和塊的概念了),根據 b+tree 的特性,在葉子頁相互之間是有指標連線的,也就是說正好兩個在數字上相鄰的鍵值,被分頁了,而聚簇索引是一頁一頁為單位的,所以可能會相距很遠.
聚族索引的優點
1.可以把相關資料儲存在一起。例如實現電子郵件時,可以根據使用者id來聚集資料,這樣只需要從磁碟讀取少數的資料頁就能獲取某個使用者的全部郵件。如果沒有使用聚族索引,則每封郵件都可能導致一次磁碟i/o;
2.資料訪問更快。聚族索引將索引和資料儲存在同乙個b-tree中,因此從聚族索引中獲取資料通常比在非聚族索引中查詢更快。
3.使用覆蓋索引掃瞄的查詢可以直接使用節點中的主鍵值。
聚族索引的缺點
1.聚簇資料最大限度的提高了i/o密集型應用的效能,但如果資料全部都放在記憶體中,則訪問的順序就沒有那麼重要了,聚簇索引也就沒有那麼優勢了;
2.插入速度嚴重依賴於插入順序。按照主鍵的順序插入是載入資料到innodb表中速度最快的方式。但如果不是按照主鍵順序載入資料,那麼在載入完成後最好使用optimize table命令重新組織一下表。
3.更新聚簇索引列的代價很高,因為會強制innodb將每個被更新的行移動到新的位置。
4.基於聚簇索引的表在插入新行,或者主鍵被更新導致需要移動行的時候,可能面臨「頁**」的問題。當行的主鍵值要求必須將這一行插入到某個已滿的頁中時,儲存引擎會將該頁**成兩個頁面來容納該行,這就是一次**操作。頁**會導致表占用更多的磁碟空間。
5.聚簇索引可能導致全表掃瞄變慢,尤其是行比較稀疏,或者由於頁**導致資料儲存不連續的時候。
6.二級索引(非聚簇索引)可能比想象的要更大,因為在二級索引的葉子節點包含了引用行的主鍵列。
7.二級索引訪問需要兩次索引查詢,而不是一次。備註:有關二級索引需要兩次索引查詢的問題?答案在於二級索引中儲存的「行指標」的實質。要記住,二級索引葉子節點儲存的不是指向行的物理位置的指標,而是行的主鍵值。這意味著通過二級索引查詢行,儲存引擎需要找到二級索引的葉子節點獲得對應的主鍵值,然後根據這個值去聚簇索引中查詢到對應的行。這裡做了重複的工作:兩次b-tree查詢而不是一次。對於innodb,自適應雜湊索引能夠減少這樣的重複工作。
聚簇索引和二級索引
前言 前面提到的innodb的頁目錄就是聚簇索引的一部分,但當有無數個頁的資料,頁目錄無法降低查詢的複雜度,所以引入了更加合適的索引 採用b 樹建立索引 常見的innodb儲存引擎就採用b 樹建立聚簇索引和二級索引。b 樹的特點 1 最底層葉子節點,存放資料。innodb存放真實的一行資料,myis...
聚簇索引與非聚簇索引(二級索引)的區別
聚簇索引 將資料儲存與索引放在一塊,找到索引也就找到了資料。非聚簇索引 將資料儲存與索引分開,索引結構的葉子節點指向資料的對應行。myisam通過key buffer把索引先快取在記憶體中,訪問資料時,在記憶體中直接搜尋索引,然後通過索引找到磁碟對應資料。注意 innodb中,在聚簇索引之上建立的索...
mysql二級索引需要回表 聚簇索引和二級索引
innodb中,在聚簇索引之上建立的索引稱之為輔助索引,非聚簇索引都是輔助索引 innodb引擎通過搜尋樹方式實現索引,索引型別分為主鍵索引 聚集索引 和 二級索引 非主鍵索引 主鍵索引樹中,葉子結點儲存著主鍵即對應行的全部資料 二級索引樹中,葉子結點儲存著索引值和主鍵值 先通過普通索引定位到主鍵值...