以前每次問到innodb和myisam引擎之間有什麼區別,總是會回答,myisam不支援事務,表鎖,非聚簇索引
innodb支援行鎖,支援事務,聚簇索引,其實innodb並非只用了聚簇索引(primary key,主鍵索引),更多的還是非聚簇索引(secondary key,輔助索引/普通索引),當然聯合索引和唯一索引也是非聚簇索引(secondary key,輔助索引/普通索引),下面把primary key都稱作:主鍵索引,secondary key都稱作:輔助索引。首先,一張表有兩種資料,乙個是表資料,乙個是索引的資料,表資料不知道是怎麼放的,索引資料,每乙個索引都是一棵b+樹結構,b+樹,葉子節點,是有序的。
myisam中的非聚簇索引
myisam的主鍵索引和輔助索引的資料結構一樣,都是b+樹,其實innodb的索引也是b+樹,都是b+樹,不同的是葉子節點儲存的內容不一樣(這裡就不講為什麼要用b+樹了,簡單來說,就是b+樹的高度比較小,減少了磁碟的io操作)。myisam的葉子節點存的是表資料這條記錄的位址(什麼位址還不知道,反正不是記憶體位址,通過這個位址,可以找到表資料檔案中的這一條資料),不管是主鍵索引還是輔助索引,都一樣,如圖:
myisam主鍵索引:
myisam輔助索引:
讀取資料的時候,根據索引b+樹很快定位到資料的位址,然後根據資料的位址取得表資料
innodb中的聚簇索引和非聚簇索引
innodb中的主鍵索引和輔助索引,結構也是b+樹,但是葉子節點中儲存的內容不一樣,主鍵索引b+樹中,葉子節點存放的是主鍵索引值和這條記錄的資料,輔助索引b+樹中,葉子節點存放的是輔助索引值和對應資料記錄的主鍵索引值,都是b+樹,但是innodb中更重視主鍵索引,從主鍵索引中取資料,很快,比myisam中通過主鍵索引取快,少了一步按位址取資料的操作,通過輔助索引取資料,會先找到主鍵索引,然後通過主鍵索引中的記錄取得資料,這個和myisam的輔助索引比,哪個更快就不知道了(感覺通過位址取得檔案的資料 還是會慢點),其他的沒有走索引的全表掃瞄,肯定是最慢的,innodb的結構如圖:
innodb主鍵索引:
innodb輔助索引:
覆蓋索引
覆蓋索引簡單來說,就是不通過查表資料,只通過查索引,就能獲取到需要的資料,通過索引直接取資料那肯定是最快的,myisam是無法做到覆蓋索引的,innodb有幾個場景可以做到覆蓋索引:
1,通過主鍵查資料,select * from table where id ???
2,通過索引查主鍵的值, select id ,index from table where index ???
3,查count , select count(id) from table 實際count(*)就是這麼做的
還有其他的,這裡就不列舉了,感覺覆蓋索引除了主鍵索引查比較常見,其他的業務需求,感覺比較難達到,只能盡量吧
b+樹的演變
二叉樹=》二叉查詢樹=》平衡二叉查詢樹=》b-樹(b樹)=》b+樹
二叉樹:乙個父節點最多兩個子節點
二叉查詢樹:乙個父節點最多兩個子節點,左子節點小於父節點,右子節點大於父節點,左小右大
平衡二叉查詢樹:滿足二叉查詢樹,並且:左右兩個子樹的高度差的絕對值不超過1(防止一棵樹一條線到底了)
b-樹(b樹):滿足平衡二叉查詢樹,但是子節點可以多個,所有葉子節點在同一層
b+樹:滿足b樹,不同的是,葉子節點存有其他資料,並且為葉子節點增加了鏈指標,將葉子節點按順序串起來了
聯合索引是多個字段組合成的乙個索引,聯合索引有些時候比單值索引要好,因為一張表索引過多,會影響插入和修改刪除的效能,但是聯合索引也有一些不太方便的地方,有乙個最左字首的規則
最左字首
如果有索引 index(a,b,c,d),那麼查詢語句,只能按順序先過濾a-》過濾b-》過濾c=》過濾d來查詢,有先後的關係,不能跳過,如果查a和c的條件,只有a會用到聯合索引,c用不到索引
mysql 索引總結 mysql索引總結
mysql中每乙個表都有乙個聚簇索引clusted index,該所索引是預設建立的,除此之外的表上的每乙個非聚簇索引都是二級索引,又叫輔助索引 secondary indexes 以innodb來說,每個innodb表具有乙個特殊的索引稱為聚集索引,如果您的表上定義有主鍵,該主鍵索引是聚集索引,如...
mysql次級索引 MySQL 索引總結
1 索引是做什麼的?想象一下,你面前有本詞典,資料就是書的正文內容,你就是那個cpu,而索引,則是書的目錄 索引用於快速找出在某個列中有一特定值的行。不使用索引,mysql必須從第1條記錄開始然後讀完整個表直到找出相關的行。表越大,花費的時間越多。如果表中查詢的列有乙個索引,mysql能快速到達乙個...
mysql 索引總結
索引用來快速地尋找那些具有特定值的記錄,所有mysql索引都以b 樹的形式儲存。如果沒有索引,執行查詢時mysql必須從第乙個記錄開始掃瞄整個表的所有記錄,直至找到符合要求的記錄。表裡面的記錄數量越多,這個操作的代價就越高。如果作為搜尋條件的列上已經建立了索引,mysql無需掃瞄任何記錄即可迅速得到...