日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

MySQL 性能调优专题一(索引数据结构详解)

發(fā)布時間:2025/3/8 数据库 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MySQL 性能调优专题一(索引数据结构详解) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

索引的本質(zhì)

索引是幫助MySQL 高效獲取數(shù)據(jù)的排好序數(shù)據(jù)結(jié)構(gòu)

MySQL 默認使用的是B+Tree數(shù)據(jù)結(jié)構(gòu)

磁盤的讀取原理

在介紹結(jié)構(gòu)之前,先簡單說下磁盤的讀取原理:

操作系統(tǒng)讀寫磁盤的基本單位是扇區(qū),而文件系統(tǒng)的基本單位是簇(Cluster)。

MySQL在存儲數(shù)據(jù)時數(shù)據(jù)都存儲在磁盤的一道道扇區(qū)中,磁盤是旋轉(zhuǎn)的,每次存儲的數(shù)據(jù)可能會存儲在不同的扇區(qū)中。

在讀取時,磁道每次需要先進行尋道操作(速度慢),磁頭只能進行左右移動,每一次尋道都是一次I/O操作。

如果數(shù)據(jù)都存在同一磁道中,那么旋轉(zhuǎn)磁盤(速度快)就可以取到數(shù)據(jù),不需要進行尋道操作,會大大減少開銷。

這里是我自己的理解,如果有不對的地方,歡迎大家指出來

索引結(jié)構(gòu)

給大家推薦一個數(shù)據(jù)結(jié)構(gòu)可視化網(wǎng)站,可以直觀的演示各種結(jié)構(gòu)

二叉樹

如果普通的一顆二叉樹,在極端情況下會退化成鏈表結(jié)構(gòu)。如圖:

紅黑樹

和二叉樹一樣,在數(shù)據(jù)量大的情況下,樹的深度太大,查詢次數(shù)過高。

比如,有500W的數(shù)據(jù),假如樹的高度有20層,你要查詢的數(shù)據(jù)剛好在葉子節(jié)點,那么需要進行20次尋道操作,和磁盤進行20次I/O交互操作,大大加大了開銷。

HASH 索引

HASH索引,相比較于B-Tree 而言,不需要從根節(jié)點到葉子節(jié)點的遍歷,可以一次定位到位置,查詢效率更高,但缺點也很明顯:

  • 僅能滿足全值查詢,不能使用范圍查詢。因為是通過HASH值進行計算,HASH值是沒規(guī)律的,所以只能精確查詢,不能保證順序和原來一致,所以不行進行范圍查詢。

  • 不能進行排序,原因如上。

  • HASH碰撞。

B+Tree

  • B+Tree 是平衡樹的一種,并且所有葉子節(jié)點位于同一層,是不會退化成鏈表結(jié)構(gòu)的。

  • B+Tree 有一個的概念,指節(jié)點的數(shù)據(jù)存儲個數(shù)。度越大,節(jié)點保存的數(shù)據(jù)個數(shù)就越多。那么相應(yīng)的樹的高度降低,在進行查詢時,需要進行的I/O操作更少,讀取數(shù)據(jù)的速度更快

  • 非葉子節(jié)點不存儲data,只存儲key,可以增大度。葉子節(jié)點只存儲data, 不存儲指針,順序訪問指針,可以提高區(qū)間訪問的性能。

  • 進行查找操作時,首先在根節(jié)點進行二分查找,找到一個key所在的指針,然后遞歸的在指針所指向的節(jié)點進行查找。直到查找到葉子節(jié)點,然后在葉子節(jié)點上進行二分查找,找出 key 所對應(yīng)的 data。

B+Tree 結(jié)構(gòu)示意圖

B+Tree 索引的性能分析

  • 一般使用磁盤I/O次數(shù)評價索引結(jié)構(gòu)的優(yōu)劣

  • 預(yù)讀:磁盤一般會順序向后讀取一定長度的數(shù)據(jù)(頁的整數(shù)倍)放入內(nèi)存。

  • 局部性原理:當一個數(shù)據(jù)被用到時,其附近的數(shù)據(jù)也通常會馬上被使用。

  • B+Tree 節(jié)點的大小設(shè)為等于一個頁,每次新建節(jié)點直接申請一個頁的空間,這樣就保證一個節(jié)點物理上也存儲在一個頁里,就實現(xiàn)了一個節(jié)點的載入只需一次I/O。

  • B+Tree 的度一般會超過100,因此高度非常小(一般為3到5之間)

MySQL 存儲引擎

MyISAM (非聚集)

  • MyISAM 索引文件和數(shù)據(jù)文件是分離的。

  • MyISAM 引擎使用B+Tree 作為索引結(jié)構(gòu),MyISAM的索引文件僅僅保存數(shù)據(jù)記錄的地址

  • MyISAM中,主索引和輔助索引在結(jié)構(gòu)上沒有任何區(qū)別,只是主索引要求key是唯一的,而輔助索引的key可以重復(fù)。

MyISAM存儲結(jié)構(gòu)示意圖

InnoDB (聚集)

  • 數(shù)據(jù)文件本身就是索引文件

  • InnoDB 引擎也使用B+Tree 作為索引結(jié)構(gòu),葉節(jié)點包含了完整的數(shù)據(jù)記錄

  • InnoDB的數(shù)據(jù)文件本身要按主鍵聚集,所以InnoDB要求表必須有主鍵(MyISAM可以沒有)。

  • InnoDB中,主鍵索引包含了完整的數(shù)據(jù)記錄,而輔助索引都引用主鍵作為data域

InnoDB存儲結(jié)構(gòu)示意圖

知道了InnoDB的索引實現(xiàn)后,就明白了為什么不建議使用過長的字段作為主鍵了,因為所有輔助索引都用主索引,過長的主索引會令輔助索引變得過大。

MyISAM和InnoDB區(qū)別

  • 事物:InnoDB支持事務(wù),可以使用 Commit 和 Rollback 語句。MyISAM不支持。

  • 并發(fā):MyISAM 只支持表級鎖,而InnoDB 還支持行級鎖。

  • 外鍵:InnoDB 支持外鍵,MyISAM不支持。

  • 備份:InnoDB 支持在線熱備份,MyISAM不支持。

  • 崩潰恢復(fù):MyISAM 崩潰后發(fā)生損壞的概率比 InnoDB 高很多,而且恢復(fù)的速度也更慢。

  • 其它特性

  • InnoDB是聚集索引,MyISAM是非聚集索引。

  • InnoDB不保存表的具體行數(shù),MyISAM用變量保存了整個表的行數(shù)。

  • InnoDB不支持全文索引,MyISAM支持全文索引。

  • MyISAM 支持壓縮表和空間數(shù)據(jù)索引。

  • 索引分類

    索引分類

    • 主鍵索引:是一種特殊的唯一索引,不允許有空值。設(shè)定為主鍵后數(shù)據(jù)庫會自動建立索引innodb為聚集索引。

    • 唯一索引:索引列中的值必須是唯一的,但是允許為空值

    • 單值索引:索引只包含單個列,但一個表中可以有多個單值索引

    • 復(fù)合索引:在表中的多個字段組合上創(chuàng)建的索引,只有在查詢條件中使用了這些字段的左邊字段時,索引才會被使用,使用組合索引時遵循最左前綴原則。

    • 全文索引:只有在MyISAM引擎上才能使用,只能在CHAR、VARCHAR、TEXT類型字段上使用全文索引,在一堆文字中,通過其中的某個關(guān)鍵字等,就能找到該字段所屬的記錄行。比如有"怡紅院、金鳳樓"等等,可以 通過金鳳樓,可能就可以找到該條記錄。

    • 空間索引:只有在MyISAM引擎上才能使用,創(chuàng)建空間索引的列,必須將其聲明為NOT NULL。空間索引是對空間數(shù)據(jù)類型的字段建立的索引,MySQL中的空間數(shù)據(jù)類型有四種,GEOMETRY、POINT、LINESTRING、POLYGON。在創(chuàng)建空間索引時,使用SPATIAL關(guān)鍵字

    最左前綴原則

    • B+Tree 是按照第一個關(guān)鍵字進行索引,然后在葉子節(jié)點上按照第一個關(guān)鍵字、第二個關(guān)鍵字、第三個關(guān)鍵字…進行排序。使用復(fù)合索引的時候,會根據(jù)你的索引順序,從左開始匹配。

    • 索引只能用于查找key是否存在(相等),遇到范圍查詢(>、<、between、like左匹配)等就不能進一步匹配了,后續(xù)退化為線性查找。

    復(fù)合索引的底層存儲結(jié)構(gòu)

    索引的優(yōu)缺點

    優(yōu)點

    • 提高查詢效率(降低IO使用率)。

    • 降低CPU使用率, 例如:...order by age desc,因為B+Tree 索引本身就是一個排好序的結(jié)構(gòu),因此在排序時可以直接使用。

    缺點

    • 索引本身很大,實際上索引也是一張表,該表保存了主鍵與索引字段,并指向?qū)嶓w表的記錄,所以索引列也是要占用空間。

    • 索引會降低增刪改的效率,MySQL不僅要保存數(shù)據(jù),還要保存一下索引文件每次更新添加了索引列的字段, 都會調(diào)整因為更新所帶來的鍵值變化后的索引信息。

    • 索引不是所有情況均適用:A. 少量數(shù)據(jù) B.頻繁更新的字段 C.很少使用的字段

    需要建立索引的情況

    • 主鍵自動建立唯一索引。

    • 頻繁作為查詢條件的字段應(yīng)該創(chuàng)建索引,WHERE 后面的語句。

    • 查詢中與其它表關(guān)聯(lián)的字段,外鍵關(guān)系建立索引。

    • 單鍵/組合索引的選擇問題,who?在高并發(fā)下傾向創(chuàng)建組合索引。

    • 查詢中排序的字段,排序字段若通過索引去訪問將大大提高排序速度。

    • 查詢中統(tǒng)計或者分組字段。

    轉(zhuǎn)載于:https://juejin.im/post/5ce4106d6fb9a07ed91196ad

    總結(jié)

    以上是生活随笔為你收集整理的MySQL 性能调优专题一(索引数据结构详解)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。