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

歡迎訪問 生活随笔!

生活随笔

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

数据库

字节一面,被连问 MySQL 索引,脸都问绿了。。。

發布時間:2025/3/21 数据库 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 字节一面,被连问 MySQL 索引,脸都问绿了。。。 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

什么是索引?

當我們使用漢語字典查找某個字時,我們會先通過拼音目錄查到那個字所在的頁碼,然后直接翻到字典的那一頁,找到我們要查的字,通過拼音目錄查找比我們拿起字典從頭一頁一頁翻找要快的多,數據庫索引也一樣,索引就像書的目錄,通過索引能極大提高數據查詢的效率。

索引的實現方式

在數據庫中,常見的索引實現方式有哈希表、有序數組、搜索樹

  • 哈希表哈希表是通過鍵值對(key-value)存儲數據的索引實現方式,可以將哈希表想象成是一個數組,將索引通過哈希函數計算得到該行數據在數組中的位置,然后將數據存到數組中,容易發現一個問題,如果兩個索引通過哈希函數計算后得到的數組位置相同要怎么辦?在這里,數組的每個value都是一個鏈表,鏈表上的每個元素都是一個數據,新數據直接添加到鏈表尾部。

    哈希表

    所以數據庫查詢過程為:索引通過哈希函數計算數據所在位置--> 遍歷指定位置的鏈表,找到滿足條件的數據。

    要注意的是,鏈表上的數據元素不是有序的,每次有新數據加入時,新數據時直接添加到鏈表尾部,這樣做的好處是添加數據時很方便。

    哈希表不擅長進行區間查詢,一般都用于等值查詢

    1、兩個相鄰索引通過hash函數后計算得到的數組位置不一定還保持相鄰

    2、鏈表上的數據是無序的

  • 有序數組顧名思義,有序數組是按索引大小將數據保存在一個數組上,因為該數組是有序的,可以通過二分法很容易查到位置,找到第一個位置后,通過向左/向右遍歷很容易得到所求區間的數據。因此,無論是等值查詢還是區間查詢,效率都極高。但缺陷也是顯而易見的,當向數組中間n位置插入一條數據時,需將n后面的數據全部往后移動,所以,這種索引一般用于靜態存儲引擎。

  • 搜索樹

二叉搜索樹:一棵空樹,或者是具有下列性質的二叉樹:若它的左子樹不空,則左子樹上所有結點的值均小于它的根結點的值;若它的右子樹不空,則右子樹上所有結點的值均大于它的根結點的值;二叉搜索樹的左、右子樹也分別為二叉搜索樹。平衡二叉樹:平衡二叉樹是在二叉搜索樹的基礎上引入的,指的是結點的左子樹和右子樹的深度差不超過1. 多叉樹:每個結點可以有多個子結點,子節點的大小從左到右依次遞增。

當使用平衡二叉實現索引時,結構如下圖

從圖中可發現,每次查詢最多需要訪問4個節點必能得到所要數據。例如查詢user2時,查詢過程為:userA-->userC-->userF-->user2。所以查詢速度很高,同時,因為搜索樹的特性(左子樹小于右子樹),區間查詢也很方便。

如果搜索樹存于內存中,與多叉樹相比,二叉樹的搜索速率是最高的,但實際上數據庫使用的是n叉樹而不是二叉樹。

1、索引不僅存于內存,還是寫到磁盤上 2、搜索樹上的每個結點在磁盤上表現為一個數據塊 3、多叉樹每個結點下可以有多個子節點,所以存儲相同數據量時多叉樹的樹高比二叉樹小,查詢一個數據需要訪問的結點數更少,即查詢過程訪問更少的數據塊。查詢速度較高。


innodb的索引模型

innodb使用B+樹作為索引結構。在B+樹中,我們將節點分為葉子結點和非葉子結點,非葉子結點上保存的是索引,而且一個節點可以保存多個索引;數據全部存于葉子結點上,根據葉子結點的內容不同,innodb索引分為主鍵索引和非主鍵索引。非主鍵索引也稱為二級索引。主鍵索引的葉子結點中保存的數據為整行數據,而非主鍵索引葉子節點保存的是主鍵的值。

主鍵索引圖

?

非主鍵索引圖

通過主鍵索引查詢數據時,我們只需查找主鍵索引樹便可以獲取數據;通過非主鍵索引查詢數據時,我們先通過非主鍵索引樹查找到主鍵值,然后再在主鍵索引樹搜索一次,這個過程稱為回表,也就是說非主鍵索引查詢會比主鍵查詢多搜索一棵樹。所以我們應盡可能使用主鍵查詢。

索引維護

添加新行時,將會在索引表上添加一條記錄,如果是索引遞增插入時,數據都是追加在當前最大索引之后,不會對樹中其他數據造成影響;如果新加入的數據的索引值位于節點的中間,需要挪動部分節點的位置,從而保持索引樹的有序性。而且,相鄰多個節點是存儲在同一個數據頁上的,此時,如果是在已經存儲滿狀態的數據頁中插入節點,會申請新的數據頁,將部分數據挪動到新的數據頁,這個過程稱為頁分裂,頁分裂除了會影響性能,還會降低磁盤空間利用率。不規則數據插入時,會造成頻繁的頁分裂。

當相鄰兩個頁由于刪除了數據,利用率很低之后,會將數據頁做合并

所以,一般情況下會采用遞增主鍵,使新數據遞增插入。

使用業務邏輯字段做主鍵有什么優缺點?

1、業務邏輯字段不容易保證索引樹結點有序插入,這樣寫入成本較高。2、innodb默認使用整數類型作為主鍵,主鍵長度較小,二級索引的葉子結點中保存的是主鍵值,主鍵長度越小,二級索引的葉子結點占用空間也就越小。3、當然,使用業務邏輯字段做主鍵也有好處,可以避免回表,每次只需掃描一次主鍵索引樹即可 綜上,從性能和存儲空間方面考量,自增主鍵往往是更合理的選擇,當業務場景有且只有一個索引,而且該索引為唯一索引時,此時更適合使用業務邏輯字段作為主鍵。

因為數據修改/刪除、頁分裂等原因,會導致數據頁空間利用率降低,此時,可以考慮重建索引,將數據按順序插入,提高磁盤空間利用率。但重建主鍵索引和普通索引會有不同影響,重建普通索引,可以達到提高空間利用率的目的,且不會對其他索引造成影響,但如果重建主鍵索引就不合理了,會影響所有普通索引,性能影響較大,而且無論是新建/刪除主鍵,都會重建整張表。這時我們可以使用alter table T engine=InnoDB這個語句代替。

查看索引利用率

查看performance_schema.table_io_waits_summary_by_index_usage表

總結

以上是生活随笔為你收集整理的字节一面,被连问 MySQL 索引,脸都问绿了。。。的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。