1. 程式人生 > 其它 >vscode 搭建 golang 開發環境

vscode 搭建 golang 開發環境

在平時的工作當中,感覺很多人經常都會碰到慢sql的情況,也就是說執行一條sql語句可能需要幾十秒甚至更長時間,那麼這種情況出現,其實大家就可以考慮sql優化的問題的,關於sql 優化,相信大部分人首先想到的就是索引,那麼關於索引的使用為什麼能提高資料的檢索速度?索引的一些原理是什麼?加了索引後索引有沒有失效?等一些問題可能很多人都不明白,其實關於資料庫優化,不僅是工作當中我們經常需要考慮到的問題,包括換工作在面試的時候也是一個會經常被問到的。當然資料優化不僅僅是加索引的問題,關於大家可以自行百度,這篇文章主要講索引底層資料結構相關原理及區別。

假如現在有一張學生學習表student_info ,包含主鍵,名稱,學號,年齡 欄位

1、索引的本質

索引是幫助MySQL高效獲取資料的排好序的資料結構。另外在學習索引的時候,都知道索引是佔實際記憶體的,也就是說索引不是說建的越多越好。為什麼說索引是排好序的資料結構,使用索引和不使用索引有什麼區別:

例如 現在使用age欄位作為索引查詢年齡等於19歲的學生資訊,select * from student_info where age = 19;

沒有使用索引的情況先,sql是全表檢索,從第一條開始,逐條開始判斷,然後返回滿足條件的記錄資料,就拿學生資訊表來說,需要檢索4次。如果是使用索引,資料結構來檢索呢?可以看到下圖二叉樹的一個數據結構,檢索的因為19大於18直接走右邊,那麼其實只要檢索3次就能找到年齡等於19歲的記錄。

可想而知,如果表的資料比較大的時候,全表逐條資料檢索就需要耗時比較長,這個大家就可以明顯感覺出使用和不使用索引的區別(當然索引的資料結構不是二叉樹,這裡只是那二叉樹來講個例子,其實索引的資料結構是B+樹,下面關於為什麼是B+樹,不是其他資料結構也有介紹)。

2、索引資料結構二叉樹、紅黑樹、B+樹詳解

二叉樹:

二叉樹特點
1)每個結點最多有兩顆子樹,所以二叉樹中不存在度大於2的結點。
2)左子樹和右子樹是有順序的,次序不能任意顛倒。
3)即使樹中某結點只有一棵子樹,也要區分它是左子樹還是右子樹。                                                                                                                                                                                                                                                                                                                    4)二叉樹的右邊的數一定大於左邊的數。             

上面在使用二叉樹描述使用索引和不使用索引的區別已經講了二叉樹的原理,那麼為什麼二叉樹不是MySQL索引的資料結構的?因為二叉樹存在斜樹的情況(如下圖 ),比如,學生資訊表,使用主鍵作為索引去查詢資料,select *  from where id = 7, 根據上圖分析,大家可以發現,二叉樹斜樹的情況下查詢資料和不使用檢索的效果都是一樣的,都是檢索7次,這也就是二叉樹的弊端。
   

紅黑樹:

R-B Tree,全稱是Red-Black Tree,又稱為“紅黑樹”,它一種特殊的二叉查詢樹。紅黑樹的每個節點上都有儲存位表示節點的顏色,可以是紅(Red)或黑(Black)。

紅黑樹的特性:
(1)每個節點或者是黑色,或者是紅色。
(2)根節點是黑色。
(3)每個葉子節點(NIL)是黑色。 [注意:這裡葉子節點,是指為空(NIL或NULL)的葉子節點!]
(4)如果一個節點是紅色的,則它的子節點必須是黑色的。
(5)從一個節點到該節點的子孫節點的所有路徑上包含相同數目的黑節點。

注意:
(01) 特性(3)中的葉子節點,是隻為空(NIL或null)的節點。
(02) 特性(5),確保沒有一條路徑會比其他路徑長出倆倍。因而,紅黑樹是相對是接近平衡的二叉樹。

如上圖,統一是主鍵id,使用紅黑樹的資料結構儲存圖,根據和二叉樹數斜樹的情況分析,可以明顯看得出和二叉樹的區別,前面有介紹到MySQL的索引是B+樹,不是二叉樹也不是紅黑樹,大家可以想想紅黑樹又有什麼弊端?

現在我們介紹的學生資訊表,資料只有幾條,假如表單資料有成千上百萬條資料,如果資料量比較大的時候,因為紅黑樹每個節點只能有兩個葉子節點,那麼也就是說會導致樹的高度比較大。因為索引的儲存在磁碟中,每次檢索都要和磁碟進行一次IO操作,如果需要查詢的資料剛好是最小葉子節點,當樹比較高的時候也就是說檢索的次數也會比較多,再加上io的操作是比較消耗效能的,所以某個程度上來講,索引使用紅黑樹的資料結構也是不合理的。紅黑樹不適用大資料量場景。

B-樹與 B+樹

基於紅黑資料不適用大資料量的場景情況,對紅黑樹進行改,比如說現在紅黑樹的高度是20,那有沒有什麼方法說可以控制樹的高度不能大於5呢?同樣大的資料量,只要能控制樹的高度不大於5,那麼sql在進行資料檢索的時候就減少的磁碟的IO操作,從這個角度來說也就提高了資料檢索的速度。其實基於對紅黑樹的這個改造也就是B 樹的資料結構(對單節點進行了擴容,是單個節點不再只是儲存一條資料)。下圖大家可以看出每個節點 不在只是儲存一個索引,而是儲存多個。

B+樹是B樹的一個升級改造版,最只要的區別是:B+樹的非葉子節點只儲存索引不儲存資料

B+樹是B樹的一個升級版,相對於B樹來說B+樹更充分的利用了節點的空間(非子節點不儲存資料,只儲存索引,這樣就可以更好的利用節點空間,存放更多的索引),讓查詢速度更加穩定,其速度完全接近於二分法查詢。為什麼說B+樹查詢的效率要比B樹更高、更穩定;我們先看看兩者的區別

(1)B+跟B樹不同B+樹的非葉子節點不儲存關鍵字記錄的指標,只進行資料索引,這樣使得B+樹每個非葉子節點所能儲存的關鍵字大大增加;

(2)B+樹葉子節點儲存了父節點的所有關鍵字記錄的指標,所有資料地址必須要到葉子節點才能獲取到。所以每次資料查詢的次數都一樣;

(3)B+樹葉子節點的關鍵字從小到大有序排列,左邊結尾資料都會儲存右邊節點開始資料的指標。

(4)非葉子節點的子節點數=關鍵字數。

(以上對紅黑樹的改造,有人可能會有疑問,既然說要控制數的高度,那幹嘛不直接都放在一個節點上,這樣就可以只進行一次磁碟IO操作,有個疑問的朋友可以想想,資料量特別大的時候,一次性把所有的資料放在一個節點上是很佔用儲存記憶體的,也就是說欲速則不達,所以關於B+樹和B樹的節點有一個合理的大小,SHOW GLOBAL STATUS LIKE 'innodb_page_size';  可以使用這個命令來檢視非葉子節點的大小,可以看到非葉子節點大小為16384個位元組,相當於16KB,為什麼設定這個大小大家可以自行百度,因為非葉子節點的大小是固定的,所以說B+樹的非葉子節點不儲存資料可以節省更多的儲存空間,存放更多的索引)

通常在B+Tree上有兩個頭指標,一個指向根節點,另一個指向關鍵字最小的葉子節點,而且所有葉子節點(即資料節點)之間是一種鏈式環結構。因此可以對B+Tree進行兩種查詢運算:一種是對於主鍵的範圍查詢分頁查詢,另一種是從根節點開始,進行隨機查詢

可能上面例子中只有22條資料記錄,看不出B+Tree的優點,下面做一個推算:

InnoDB儲存引擎中頁的大小為16KB,一般表的主鍵型別為 INT(佔用4個位元組)或 BIGINT(佔用8個位元組),指標型別也一般為4或8個位元組,也就是說一個頁(B+Tree中的一個節點)中大概儲存16KB/(8B+8B)=1K個鍵值。(因為是估值,為方便計算,這裡的K取值為〖10〗3)。也就是說一個深度為3的B+Tree索引可以維護103 * 10^3 * 10^3 = 10億 條記錄。

實際情況中每個節點可能不能填充滿,因此在資料庫中,B+Tree的高度一般都在24層。MySQL的InnoDB儲存引擎在設計時是將根節點常駐記憶體的,也就是說查詢某一鍵值的行記錄時最多隻需要13次磁碟I/O操作。

資料庫中的B+Tree索引可以分為聚集索引(clustered index)和 輔助索引(secondary index)。上面的B+Tree示例圖在資料庫中的實現即為聚集索引,聚集索引的B+Tree中的葉子節點存放的是整張表的行記錄資料。

輔助索引與聚集索引的區別在於輔助索引的葉子節點並不包含行記錄的全部資料,而是儲存相應行資料的聚集索引鍵,即主鍵。當通過輔助索引來查詢資料時,InnoDB儲存引擎會遍歷輔助索引找到主鍵,然後再通過主鍵在聚集索引中找到完整的行記錄資料。

檢視mysql檔案頁大小(16K):SHOW GLOBAL STATUS like 'Innodb_page_size’;

Hash資料結構

定義:(Hash table,也叫雜湊表),是根據關鍵碼值(Key value)而直接進行訪問的。也就是說,它通過把關鍵碼值對映到表中一個位置來訪問記錄,以加快查詢的速度。這個對映函式叫做,存放記錄的叫做。 對目標值進行hash運算得到hash值和資料磁碟指標地址儲存到hash表,這樣就達到快速定位資料位置。

缺點:精確查詢十分快速,但範圍查詢就碰壁了。
image.png