1. 程式人生 > 實用技巧 >MySql的索引分類、資料結構以及優化細節

MySql的索引分類、資料結構以及優化細節

文章目錄

實操案例: 選錯「索引」導致的線上慢查詢
explain指令:MySQL Explain詳解

B樹和B+樹各自的優勢:為什麼 Mongodb 索引用 B 樹,而 Mysql 用 B+ 樹?

索引的分類

  • 主鍵索引(不允許空值)
  • 唯一索引(允許空值)
  • 普通索引(其他普通列)
  • 全文索引(關鍵字查詢,mysql不推薦用)
  • 組合索引(一個索引包含多個列)

mysql資料結構

  • 樹形結構的演化
    二叉樹->BST(banary search tree,實現了二分查詢,但是插入遞增資料的話,會退化成近似連結串列的結構)->AVL Tree

    (自動旋轉,最短子樹和最長子樹高度之差不超過1,查詢效能提升是以插入效能降低為前提的)-> BRT(black red tree,最長子樹和最短子樹高度之差不超過1倍,在插入效能以及查詢效能之間做了平衡,適用於插入頻率和查詢頻率近似相等的場景)

  • mysql為什麼不使用以上樹形結構

    • IO讀取資料的最小單位是頁(8K/16K等),每個節點上的資料不能保證對齊;
    • 資料量大的時候,樹型結構變深,增加IO次數,降低效率。
  • B-Tree

    • b樹有個概念叫degree,可以定義每個節點儲存的資料量(多個數據可以存放進一個節點,可以作為一個數據頁)。
      在這裡插入圖片描述

    • b樹模型(InnoDB預設載入16K)
      在這裡插入圖片描述

  • B+樹模型(非葉子節點全部存放指標和索引,資料全部放進葉子結點,減小了樹的深度,提高查詢效率),三層B+樹可以支撐千萬級別的資料量

  • B+樹所有的葉子結點之間存在雙向連結串列。
    在這裡插入圖片描述

在這裡插入圖片描述

  • InnoDB–B+Tree,葉子結點直接存放資料

在這裡插入圖片描述

在這裡插入圖片描述

  • 每建一個索引,就會有一顆B+樹,換言之,一張表裡可以有多棵樹,但是帶有原始資料的tree只有一顆(如下例子,name列也建立了索引,name樹葉子節點存放的就是主鍵id的值)。
    在這裡插入圖片描述

面試常問名詞

  • 回表:先查name樹查到id值,再查id樹找到資料,這樣查多棵樹的行為叫做回表,應該儘量避免。
  • 索引覆蓋:查詢的索引資訊包含查詢資料,不需要回表即可返回資料,稱為索引覆蓋。

select id,name from tbl where name=‘zhang’;
select * from tbl where name=‘zhang’;

此兩種方式查詢過程不一樣。

  • 最左匹配:針對於組合索引,優先過濾不符合最左定義的索引的資料。

name age 組合索引
where name = ? and age = ?
where name = ?
where age = ?
where age = ? and name = ? 依然會走最左匹配,優化器優化

  • 索引下推:針對於組合索引,5.6之後根據name,age兩個列的值去獲取資料,直接返回(減少了整體io量)。

在這裡插入圖片描述

Mysql優化小細節

  • 當使用索引列進行查詢的時候,儘量不要使用表示式,把計算放在業務層而不是資料庫層;

  • 儘量使用主鍵查詢,而不是其他索引,因為主鍵查詢不會觸發回表查詢(主鍵最好自增,否則不好維護,大小亂序會造成葉子結點分裂);

  • 使用索引的選擇性。如果主鍵是varchar且較長(uuid),可以使用left(uid,7)來建立索引。
    在這裡插入圖片描述

  • 強制型別轉化,會使索引失效,進行全盤掃描。
    在這裡插入圖片描述

  • 更新十分頻繁,資料區分度不高的欄位不宜建立索引。
    在這裡插入圖片描述

  • 索引列不允許為null(mybatis會把0當做null);

  • 表連線查詢最好不要超過三張表;

  • 能使用limit儘量使用limit,減少IO量;

  • 建立索引應避免以下認知:

    • 索引越多越好
    • 過早優化,在不瞭解系統的情況下進行優化