mysql 索引總結 mysql索引總結

2021-10-19 18:34:09 字數 3875 閱讀 6488

mysql中每乙個表都有乙個聚簇索引clusted index,該所索引是預設建立的,除此之外的表上的每乙個非聚簇索引都是二級索引,又叫輔助索引(secondary indexes)。

以innodb來說,每個innodb表具有乙個特殊的索引稱為聚集索引,如果您的表上定義有主鍵,該主鍵索引是聚集索引,如果你不定義為你的表的主鍵是,mysql取第乙個唯一索引unique而且只含非空列(not null)作為主鍵,innodb使用它作為聚集索引,如果沒有這樣的列,innodb就自己產生這樣的id值,它有留個位元組,而且是隱藏的,使其作為聚簇索引。

根據資料的功能,可以在資料庫設計器中建立三種索引:唯一索引、主鍵索引和聚集索引

唯一所以是不允許其中任何兩行具有相同的索引值的索引

主鍵索引資料庫表經常有一列或列組合、其值唯一標識表中的每一行,該列稱為表的主鍵。在資料庫關係圖中為表定義主鍵將自動建立主鍵索引,主鍵索引是唯一索引的特定型別。該索引要求主鍵中的每個值都唯一。

聚集索引 在聚集索引中,表中行的物理順序與鍵值的邏輯順序相同,乙個表只能包含乙個聚集索引

區域性性原理與磁碟預讀

由於儲存介質的特性,磁碟本身訪問就比主存慢很多,再加上機械運動耗費,磁碟的訪問速度往往是主存的幾百分之一甚至6000倍,因此為了提公升效率,要儘量減少磁碟i/o,為了達到這個目的,磁碟往往不是嚴格按需讀取,而是每次讀都會預讀,即使只需要乙個位元組,磁碟也會從這個位置開始,順序向後讀取一定長度的資料存放入記憶體。這樣做的理論依據是電腦科學中最著名的區域性性原理,即當乙個資料被用到時,其附近的資料也通常會被使用。程式執行期間所需的資料通常比較集中。

由於磁碟順序讀取的效率很高(不需要尋道時間,只需要很少的旋轉時間),因此對於具有區域性性的程式來說,預讀可以提高i/o效率

預讀的長度一般為頁page的整數倍。頁是計算機管理儲存器的邏輯快,硬體以及作業系統往往將主存很磁碟儲存區分割為連續大小相等的塊,每個儲存塊稱為一頁(在許多作業系統中,頁的大小通常為4k),主存和磁碟以頁為單位交換資料。當程式要讀取的資料不在主存中時,會觸發乙個缺頁異常,因此系統會向磁碟傳送出讀盤訊號,磁碟會找到資料的起始位置並向後連續的一頁或者幾頁記憶體中,然後異常返回,程式繼續執行。

b-/+ tree 索引的效能分析

上文說過,一般使用磁碟i/o次數評價索引結構的優劣,先從b-tree分析,根據b-tree的定義,可知檢索一次最多需要訪問h個節點。資料庫系統的設計者巧妙的利用了磁碟與讀寫原理,將乙個節點的大小設定為等於乙個頁,這樣每個節點只需要一次i/o就可以完全載入,為了達到這個目的,在實際實現b-tree還需要使用如下技巧:

每次新建節點時,直接申請乙個頁的空間,這樣就保證乙個節點物理上也儲存在乙個頁裡,加之計算機儲存分配都是按頁對齊的,就實現了乙個node只需一次i/o。

b-tree中一次檢索最多需要h-1次i/o(根節點常駐記憶體),漸進複雜度為o(h)=o(logdn)。一般實際應用中,出度d是非常大的數字,通常超過100,因此h非常小(通常不超過3)。

而紅黑樹這種結構,h明顯要深的多。由於邏輯上很近的節點(父子)物理上可能很遠,無法利用區域性性,所以紅黑樹的i/o漸進複雜度也為o(h),效率明顯比b-tree差很多。

3.資料庫結構優化

1)正規化優化: 比如消除冗餘(節省空間。。) 2)反正規化優化:比如適當加冗餘等(減少join) 3)拆分表: 分割槽將資料在物理上分隔開,不同分割槽的資料可以制定儲存在處於不同磁碟上的資料檔案裡。這樣,當對這個表進行查詢時,只需要在表分割槽中進行掃瞄,而不必進行全表掃瞄,明顯縮短了查詢時間,另外處於不同磁碟的分割槽也將對這個表的資料傳輸分散在不同的磁碟i/o,乙個精心設定的分割槽可以將資料傳輸對磁碟i/o競爭均勻地分散開。對資料量大的時時錶可採取此方法。可按月自動建表分割槽。

4)拆分其實又分垂直拆分和水平拆分: 案例: 簡單購物系統暫設涉及如下表: 1.產品表(資料量10w,穩定) 2.訂單表(資料量200w,且有增長趨勢) 3.使用者表 (資料量100w,且有增長趨勢) 以mysql為例講述下水平拆分和垂直拆分,mysql能容忍的數量級在百萬靜態資料可以到千萬垂直拆分:解決問題:表與表之間的io競爭 不解決問題:單錶中資料量增長出現的壓力 方案: 把產品表和使用者表放到乙個server上 訂單表單獨放到乙個server上水平拆分:解決問題:單錶中資料量增長出現的壓力 不解決問題:表與表之間的io爭奪

方案: 使用者表通過性別拆分為男使用者表和女使用者表 訂單表通過已完成和完成中拆分為已完成訂單和未完成訂單 產品表 未完成訂單放乙個server上 已完成訂單表盒男使用者表放乙個server上 女使用者表放乙個server上(女的愛購物 哈哈)

b+索引原理

在b+索引樹中,非葉子節點由索引元素和指向子節點的指標組成,他們的作用就是找到葉子節點,因為只有葉子節點中有最終要找到資料資訊。從圖中可以看出節點中指標的數量比索引元素數量多乙個,在葉子節點中,因為沒有子節點,多出的那個指標指向下乙個葉子節點,這樣把所有的葉子節點串聯起來,這對於範圍搜尋很有用。在實際應用中乙個節點的大小是固定的通常等於磁碟乙個頁的大小,這樣訪問乙個節點只要一次磁碟io,一般節點可存上百個元素,所以索引幾百萬資料b+樹高不會超過3。

搜尋類似於二叉查詢樹,從根節點開始自頂向下遍歷,直到葉子節點,在節點內部典型的使用二分查詢來確定位置。

innodb儲存的資料本身就是主鍵b+樹索引,因為索引記憶體儲存這真實的資料。

innodb支援事務,外來鍵,mvcc,行鎖這些更先進的引擎技術。

主鍵primary key 必須唯一,不同的是不能有null。而且乙個表只能有乙個主鍵,有很多人認為主鍵是唯一索引的一種,其實是不準確的。主鍵也可以是組合索引,只要組合的每條結果是唯一的,這在某些場景非常實用,比如乙個多對多關係中的樞紐表就非常適合使用復合主鍵。下圖就是乙個典型的使用者許可權功能的實現,使用者和角色、角色和許可權都是多對多的關係,主要樞紐表來記錄他們之間的對應關係,而這些關係都是唯一的,所以這種樞紐錶用復合主鍵非常合適。

選擇區分度高的列作為索引

區分度:count(distinct col)/count(*),區分度是乙個介於0和1的小數,越接近1區分度越高,

mysql建立索引的基本原則:

1、不要在低基數列建立索引。浪費索引儲存空間,並且不會提供查詢的效率。

2、盡量不要在經常被修改的子段上建立索引,會增加插入的成本,以及提高死鎖發生的概率。

3、刪除冗餘索引,沒有用到的索引必須全部刪除,避免不必要的空間浪費。本示例中url索引是無用的。

4、不要建立太多的索引,因為插入資料時,索引也需要插入。索引太多會導致插入效能下降

5、不要在非null列建立索引,如果值為null是,建議替換成1或者-1等常量

6、如果查詢的是多條件,不要為每個條件建立索引,而是建立復合索引,因為mysql只用使用1個索引

7、建立復合索引,注意是左匹配原則,將兩考慮重用性。比如建立復合索引index(a,b,c),相當於同時建立index(a),index(a、b),index(a,b,c)。

8、建立復合索引,需要注意把分度最大的放在最前面

9、主鍵最好使用自增型,保證資料連續性(mysql innodb主鍵預設採用b+tree,索引和資料 放在同乙個tree中,)不要使用uuid、hash、md5等

10、少使用外來鍵,會導致兩張表資料變更時相互影響。盡量通過業務實現。

11、不要使用前匹配的like查詢,會導致索引失效,可以使用後匹配like「***x%」

12、在字串上建立索引、盡量使用字首索引。字首技術根據具體業務,在匹配度和儲存量(索引的儲存量)之間做乙個平衡。

13、不要使用not in like,會導致索引失效。not in 可以用not in可以用not exist替換。in和or所在列最好有索引

索引的選擇性是指不重複的索引值(基數)和資料表記錄總數的比值,從1#t之間。索引的選擇性越高則查詢的效率越高,因為選擇性越高的索引可以讓mysql在查詢時過濾掉更多的行。唯一所以索引的選擇性是1,這是最好的索引,這是最好的索引選擇性,效能也是最好的

一般情況下某個字首的選擇性天然就是足夠高的,足以滿足查詢效能,對於blob text或者很長的varchar 型別的列,比如使用字首索引,因為mysql不允許索引這些列的的完成長度。

mysql 雜湊索引 MySQL索引之雜湊索引

雜湊索引 hash index 建立在雜湊表的基礎上,它只對使用了索引中的每一列的精確查詢有用。對於每一行,儲存引擎計算出了被索引的雜湊碼 hash code 它是乙個較小的值,並且有可能和其他行的雜湊碼不同。它把雜湊碼儲存在索引中,並且儲存了乙個指向雜湊表中的每一行的指標。在mysql中,只有me...

mysql主鍵索引 MySQL索引之主鍵索引

在mysql裡,主鍵索引和輔助索引分別是什麼意思,有什麼區別?上次的分享我們介紹了聚集索引和非聚集索引的區別,本次我們繼續介紹主鍵索引和輔助索引的區別。1 主鍵索引 主鍵索引,簡稱主鍵,原文是primary key,由乙個或多個列組成,用於唯一性標識資料表中的某一條記錄。乙個表可以沒有主鍵,但最多只...

mysql聚集索引 MySQL索引之聚集索引介紹

在mysql裡,聚集索引和非聚集索引分別是什麼意思,有什麼區別?在mysql中,innodb引擎表是 聚集 索引組織表 clustered index organize table 而myisam引擎表則是堆組織表 heap organize table 也有人把聚集索引稱為聚簇索引。當然了,聚集索...