一、聚集索引(聚簇索引)
1. 什么是聚集索引?
比如要查找'hello',則直接找內容為hello的行,我們把這種正文內容本身就是一種按照一定規則排列的目錄稱為“聚集索引”。
聚集索引的葉子節點就是數據節點,key為主鍵的值,value為其余列數據以及rowid、rollback pointer、trx id等信息。
聚集索引的條件:
a.首先選擇顯示定義的主鍵為聚集索引;
b.如果沒有則選擇第一個非NULL的唯一索引;
c.以上都不滿足就選擇ROWID。
聚集索引表現:
a.索引的鍵值順序決定了表中相應行的物理順序,即表中行的存儲順序由聚集索引的鍵值順序決定;
b.一個表只能有一個聚集索引;
c.索引列可能是多個(復合索引)。
2. 適用場景(只針對innodb存儲引擎,myisam不存在這說法)
a.主鍵列,該列在where子句中使用並且插入是隨機的。
b.按范圍存取的列,如pri_order > 100 and pri_order < 200。
c.在group by或order by中使用的列。
d.不經常修改的列,不能建立在自增列上。
e.在連接操作中使用的列。
二、非聚集索引
1.比如要尋找一個繁體字,得先找到它對應的前一個和后一個字的頁碼,通過頁碼來找到對應內容,把這種通過頁碼來尋找的方式稱為非聚集索引。
非聚集索引的葉子節點為索引節點,但是有一個指針指向數據節點。
非聚集索引就是普通索引,僅僅是對表創建索引不會影響表的物理存儲順序,非聚集索引的寫入順序由時間順序決定。
2.對更新頻繁的表來說,表上的非聚簇索引比聚集索引和根本沒有索引需要更多的額外開銷。對移到新頁的每一行而言,指向該數據的每個非聚簇索引的頁級行也必須更新,有時可能還需要索引頁的分理。
3.適用場景
a.常用於計算函數如sum/count的列;
b.常用於join/order by/group by的列;
c.查尋出的數據不超過表中數據量的20%。
三、總結
四、索引優化
1、缺省情況下建立的索引是非聚簇索引,但有時它並不是最佳的。在非群集索引下,數據在物理上隨機存放在數據頁上。合理的索引設計要建立在對各種查詢的分析和預測上。一般來說:
a.有大量重復值、且經常有范圍查詢( > ,< ,> =,< =)和order by、group by發生的列,可考
慮建立聚集索引;
b.經常同時存取多列,且每列都含有重復值可考慮建立組合索引;
c.組合索引要盡量使關鍵查詢形成索引覆蓋,其前導列一定是使用最頻繁的列。索引雖有助於提高性能但不是索引越多越好,恰好相反過多的索引會導致系統低效。用戶在表中每加進一個索引,維護索引集合就要做相應的更新工作。
2、ORDER BY和GROPU BY使用ORDER BY和GROUP BY短語,任何一種索引都有助於SELECT的性能提高。
3、多表操作在被實際執行前,查詢優化器會根據連接條件,列出幾組可能的連接方案並從中找出系統開銷最小的最佳方案。連接條件要充份考慮帶有索引的表、行數多的表;內外表的選擇可由公式:外層表中的匹配行數*內層表中每一次查找的次數確定,乘積最小為最佳方案。
4、任何對列的操作都將導致表掃描,它包括數據庫函數、計算表達式等等,查詢時要盡可能將操作移至等號右邊。
5、IN、OR子句常會使用工作表,使索引失效。如果不產生大量重復值,可以考慮把子句拆開。拆開的子句中應該包含索引。