索引,相似書籍的目錄,能夠根據目錄的某個頁碼當即找到對應的內容。java
索引的優勢:1. 天生排序。2. 快速查找。
索引的缺點:1. 佔用空間。2. 下降更新表的速度。mysql
注意點:小表使用全表掃描更快,中大表才使用索引。超級大表索引基本無效。算法
索引從實現上說,分紅 2 種:彙集索引和輔助索引(也叫二級索引或者非彙集索引)sql
從功能上說,分爲 6 種:普通索引,惟一索引,主鍵索引,複合索引,外鍵索引,全文索引。數據庫
詳細說說 6 種索引:網絡
一、普通索引:最基本的索引,沒有任何約束。
二、惟一索引:與普通索引相似,但具備惟一性約束。
三、主鍵索引:特殊的惟一索引,不容許有空值。
四、複合索引:將多個列組合在一塊兒建立索引,能夠覆蓋多個列。
五、外鍵索引:只有InnoDB類型的表纔可使用外鍵索引,保證數據的一致性、完整性和實現級聯操做。
六、全文索引:MySQL 自帶的全文索引只能用於 InnoDB、MyISAM ,而且只能對英文進行全文檢索,通常使用全文索引引擎(ES,Solr)。併發
注意:主鍵就是惟一索引,可是惟一索引不必定是主鍵,惟一索引能夠爲空,可是空值只能有一個,主鍵不能爲空。
另外,InnoDB 經過主鍵聚簇數據,若是沒有定義主鍵且沒有定義彙集索引, MySql 會選擇一個惟一的非空索引代替,若是沒有這樣的索引,會隱式定義個 6 字節的主鍵做爲聚簇索引,用戶不能查看或訪問。異步
簡單點說:性能
MySql 將數據按照頁來存儲,默認一頁爲 16kb,當你在查詢時,不會只加載某一條數據,而是將這個數據所在的頁都加載到 pageCache 中,這個其實和 OS 的就近訪問原理相似。優化
MySql 的索引使用 B+ 樹結構。在說 B+ 樹以前,先說說 B 樹,B 樹是一個多路平衡查找樹,相較於普通的二叉樹,不會發生極度不平衡的情況,同時也是多路的。
B 樹的特色是:他會將數據也保存在非頁子節點。
看圖可知:
而這個特色會致使非頁子節點不能存儲大量的索引。
而 B+ Tree 就是針對這個對 B tree 作了優化。以下圖所示:
咱們看到,B+ Tree 將全部的 data 數據都保存到了葉子節點中,非也子節點只保存索引和指針。
咱們假設一個非頁子節點是 16kb,每一個索引,即主鍵是 bigint,即 8b,指針爲 8b。那麼每頁能存儲大約 1000 個索引(16kb/ 8b + 8b).
而一顆 3 層的 B+樹可以存儲多少索引呢?以下圖:
大約可以存儲 10 億個索引。一般 B+ 樹的高度在 2-4 層,因爲 MySql 在運行時,根節點是常駐內存的,所以每次查找只須要大約 2 -3 次 IO。能夠說,B+ 樹的設計,就是根據機械磁盤的特性來進行設計的。
知道了索引的設計,咱們可以知道另一些信息:
那麼,若是項目中使用了分庫分表,咱們一般都會須要一個主鍵進行 sharding,那怎麼辦呢?在實現上,咱們能夠保留自增主鍵,而邏輯主鍵用來做爲惟一索引便可。
關於 Mysql 的鎖,各類概念就會噴涌而出,事實上,鎖有好幾種維度,咱們來解釋一下。
排它鎖(寫鎖 / X 鎖)
類型細分:
悲觀鎖(使用鎖,即 for update)
能夠選擇手動上鎖:select xxxx for update (排他鎖); select xxxx lock in share mode(共享鎖),稱之爲「一致性鎖定讀」。
使用鎖以後,就能在 RR 級別下,避免幻讀。固然,默認的 MVCC 讀,也能避免幻讀。
既然 RR 可以防止幻讀,那麼,SERIALIZABLE 有啥用呢?
防止丟失更新。例以下圖:
這個時候,咱們必須使用 SERIALIZABLE 級別進行串行讀取。
最後,行鎖的實現原理就是鎖住彙集索引,若是你查詢的時候,沒有正確地擊中索引,MySql 優化器將會拋棄行鎖,使用表鎖。
事務是數據庫永恆不變的話題, ACID:原子性,一致性,隔離性,持久性。
四個特性,最重要的就是一致性。而一致性由原子性,隔離性,持久性來保證。
而後再說隔離性。
隔離級別:
每一個級別都會解決不一樣的問題,一般是3 個問題:髒讀,不可重複讀,幻讀。一張經典的圖:
這裏有個注意點,關於幻讀,在數據庫規範裏,RR 級別會致使幻讀,可是,因爲 Mysql 的優化,MySql 的 RR 級別不會致使幻讀:在使用默認的 select 時,MySql 使用 MVCC 機制保證不會幻讀;你也可使用鎖,在使用鎖時,例如 for update(X 鎖),lock in share mode(S 鎖),MySql 會使用 Next-Key Lock 來保證不會發生幻讀。前者稱爲快照讀,後者稱爲當前讀。
原理剖析:
那 RR 和 Serializble 有什麼區別呢?答:丟失更新。本文關於鎖的部分已經提到。
MVCC 介紹:全稱多版本併發控制。
innoDB 每一個彙集索引都有 4 個隱藏字段,分別是主鍵(RowID),最近更改的事務 ID(MVCC 核心),Undo Log 的指針(隔離核心),索引刪除標記(當刪除時,不會當即刪除,而是打標記,而後異步刪除);
本質上,MVCC 就是用 Undo Log 鏈表實現。
MVCC 的實現方式:事務以排它鎖的方式修改原始數據,把修改前的數據存放於 Undo Log,經過回滾指針與數據關聯,若是修改爲功,什麼都不作,若是修改失敗,則恢復 Undo Log 中的數據。
多說一句,一般咱們認爲 MVCC 是相似樂觀鎖的方式,即便用版本號,而實際上,innoDB 不是這麼實現的。固然,這不影響咱們使用 MySql。
https://mp.weixin.qq.com/s/XwC9n2Ik_DrfY-ERd99wqA