通常情況下,建立索引是加快查詢速度的有效手段。但索引不是萬能的,靠索 引並不能實現對所有數據的快速存取。事實上,如果索引策略和數據檢索需求嚴重不符的話,建立索引反而會降低查詢性能。因此在實際使用當中,應該充分考慮到 索引的開銷,包括磁盤空間的開銷及處理開銷(如資源競爭和加鎖)。例如,如果數據頻繁的更新或刪加,就不宜建立索引。
- 建立索引:
- 存儲特點:
- 聚集索引。表數據按照索引的順序來存儲的,也就是說索引項的順序與表中記錄的物理順序一致。對於聚集索引,葉子結點即存儲了真實的數據行,不再有另外單獨的數據頁。 在一張表上最多只能創建一個聚集索引,因為真實數據的物理順序只能有一種。
- 非聚集索引。表數據存儲順序與索引順序無關。對於非聚集索引,葉結點包含索引字段值及指向數據頁數據行的邏輯指針,其行數量與數據表行數據量一致。
- 更新表數據
如果一張表沒有聚集索引,那么它被稱為“堆集”(Heap)。這樣的表中的數據行沒有特定的順序,所有的新行將被添加到表的末尾位置。而建立了聚簇索引的數據表則不同:最簡單的情況下,插入操作根據索引找到對應的數據頁,然后通過挪動已有的記錄為新數據騰出空間,最后插入數據。如果數據頁已滿,則需要拆分數據頁,調整索引指針(且如果表還有非聚集索引,還需要更新這些索引指向新的數據頁)。而類似於自增列為聚集索引的,數據庫系統可能並不拆分數據頁,而只是簡單的新添數據頁。
2、從表中刪除數據行
對刪除數據行來說:刪除行將導致其下方的數據行向上移動以填充刪除記錄造成的空白。如果刪除的行是該數據頁中的最后一行,那么該數據頁將被回收,相應的索 引頁中的記錄將被刪除。對於數據的刪除操作,可能導致索引頁中僅有一條記錄,這時,該記錄可能會被移至鄰近的索引頁中,原索引頁將被回收,即所謂的“索引 合並”。
建立聚簇索引的思想
不知從什么角度來對比,只能說說各自的特點,希望對你有用。
1、聚簇索引
a) 一個索引項直接對應實際數據記錄的存儲頁,可謂“直達”
b) 主鍵缺省使用它
c) 索引項的排序和數據行的存儲排序完全一致,利用這一點,想修改數據的存儲順序,可以通過改變主鍵的方法(撤銷原有主鍵,另找也能滿足主鍵要求的一個字段或一組字段,重建主鍵)
d) 一個表只能有一個聚簇索引(理由:數據一旦存儲,順序只能有一種)
2、非聚簇索引
a) 不能“直達”,可能鏈式地訪問多級頁表后,才能定位到數據頁
b) 一個表可以有多個非聚簇索引
第二種理解:
聚簇索引是對磁盤上實際數據重新組織以按指定的一個或多個列的值排序的算法。特點是存儲數據的順序和索引順序一致。
一般情況下主鍵會默認創建聚簇索引,且一張表只允許存在一個聚簇索引。
在《數據庫原理》一書中是這么解釋聚簇索引和非聚簇索引的區別的:
聚簇索引的葉子節點就是數據節點,而非聚簇索引的葉子節點仍然是索引節點,只不過有指向對應數據塊的指針。
因此,MYSQL中不同的數據存儲引擎對聚簇索引的支持不同就很好解釋了。
下面,我們可以看一下MYSQL中MYISAM和INNODB兩種引擎的索引結構。
如原始數據為:

MyISAM引擎的數據存儲方式如圖:

MYISAM是按列值與行號來組織索引的。它的葉子節點中保存的實際上是指向存放數據的物理塊的指針。
從MYISAM存儲的物理文件我們能看出,MYISAM引擎的索引文件(.MYI)和數據文件(.MYD)是相互獨立的。
而InnoDB按聚簇索引的形式存儲數據,所以它的數據布局有着很大的不同。它存儲數據的結構大致如下:

注:聚簇索引中的每個葉子節點包含主鍵值、事務ID、回滾指針(rollback pointer用於事務和MVCC)和余下的列(如col2)。
INNODB的二級索引與主鍵索引有很大的不同。InnoDB的二級索引的葉子包含主鍵值,而不是行指針(row pointers),這減小了移動數據或者數據頁面分裂時維護二級索引的開銷,因為InnoDB不需要更新索引的行指針。其結構大致如下:

INNODB和MYISAM的主鍵索引與二級索引的對比:

InnoDB的的二級索引的葉子節點存放的是KEY字段加主鍵值。因此,通過二級索引查詢首先查到是主鍵值,然后InnoDB再根據查到的主鍵值通過主鍵 索引找到相應的數據塊。而MyISAM的二級索引葉子節點存放的還是列值與行號的組合,葉子節點中保存的是數據的物理地址。所以可以看出MYISAM的主 鍵索引和二級索引沒有任何區別,主鍵索引僅僅只是一個叫做PRIMARY的唯一、非空的索引,且MYISAM引擎中可以不設主鍵
