HASH演算法介紹

2021-10-09 03:16:08 字數 2523 閱讀 1818

在oracle中使用頻率最高的演算法就是hash演算法接下來以共享池中的sql語句查詢為例,描述hash演算法

最簡單的hash就是求餘給它乙個值可以生成另乙個值。

hash演算法的核心就是設計乙個hash函式,每次傳給它乙個給定值(源值,也稱為hash的key),可以得到另外乙個相應的值(hash值)。hash函式就是將源值(hash key)轉化為hash值的過程,而且此過程是可重複的。

例如,以「除以31取余為例」,除以31取餘可以稱為hash函式,假設傳給這個hash函式乙個值50,得到的結果為19,那麼這個值19就是hash值。而這個被傳給它的50則是hash key。

除法或者求余會占用非常高的cpu資源並且無法應用於字串,所以大部分hash函式都是位運算的。位運算是乙個速度很快的操作,相比較除法和求餘。位運算只會占用很少的cpu資源。但hash函式仍然是強cpu消耗型操作,因此在hash演算法使用比較密集的時候,cpu的佔用率一定會居高不下。在oracle中比如邏輯讀。每一次邏輯讀都要計算hash值,然後根據這個hash值來找到cache buffer chain鍊錶,因此邏輯讀是一種很消耗cpu的操作。

通過hash演算法將各種各樣的sql語句轉化成乙個數值,目的就是快速搜尋。

2.1 使用遍歷演算法查詢鍊錶

**  在oracle中,hash演算法的作用主要是快速搜尋。而搜尋目標就是記憶體,通過hash在記憶體中快速定位。**記憶體中的資料組織成煉表,其組織形式如下。

解釋一下上圖的含義,通常在乙個鍊錶中會存在乙個表頭,表頭會記錄下一記憶體塊的資訊。上圖中記憶體塊a的位址是10000,在a中儲存了語句select * from t1 where c1=100的相關資訊,同時記憶體塊a也將記憶體塊b的位址記錄下來。以此類推記憶體塊b也記錄了乙個語句的資訊和c的位址。c是這個鍊錶的最後乙個所以記錄的除了語句外沒有下一記憶體塊的位址為null。需要注意的是這些記憶體塊不是相連的而是記錄位址的關係。

具體執行流程

現在想檢視「select * from t1 where c1=101;」這條sql的相關資訊,從鍊錶頭部開始步驟如下

訪問10000處的記憶體塊,檢視裡面的語句和想要查詢的目標語句是否一致,不是的話去這個記憶體塊所記錄的下一目標塊檢視。

訪問13000處的記憶體塊,發現裡面的語句和要查詢的目標語句一致,發現這就是要找的目標。

訪問13000處記憶體塊相關資訊。

以上的執行方式就是資料結構中最初級的方法——遍歷演算法。在鍊錶中搜尋某個記憶體塊,像這種從頭到尾比較每乙個記憶體塊就是鍊錶的遍歷演算法,當然如果鍊錶很長那麼查詢的時間也會變得很長,所以在查詢長鍊表的時候遍歷演算法的效率很低。也因此產生了更高效的hash演算法。

2.2 使用hash演算法查詢

遍歷演算法對記憶體塊的存放沒有要求,但是hash演算法要求記憶體塊必須都是相連的,並且記憶體塊的順序也有要求。具體如下:

還是上例中的3條sql,3塊記憶體對應的3條sql的hash值和hash值除以3的餘數如下:

記憶體塊語句內容

hash值

除以3的餘數

記憶體塊a

select * from t1 where c1 = 100

468183

0記憶體塊b

select * from t1 where c1 = 101

472279

1記憶體塊c

select * from t1 where c1 = 100

911081

2在記憶體中排序相應如下:

記憶體分配方式:假設每個記憶體塊為300位元組,那麼這三個記憶體塊共需要記憶體分配900位元組。並且根據表中計算出來的餘數,記憶體塊的應該以a、b、c的順序排放在記憶體中如上圖所示。a的記憶體位址為20000,b的記憶體位址為20300,c的記憶體位址為20600。這樣做的好處是每個記憶體塊不需要再記錄下一記憶體塊的位址了,因為記憶體塊的大小是一樣並且有一定的順序,在本記憶體塊的記憶體位址上加300就可以了。

使用hash演算法來查詢鍊錶直接將要查詢的內容作為hashkey並計算hash值然後再求餘。這裡每塊記憶體被oracle命名為hash bucket,這三個hash bucket組合成為hash表。而hash bucket的編號來自於餘數。

具體執行流程

現在檢視「select * from t1 where c1=101;」這條sql的相關資訊

2.3 兩種查詢的區別

在鍊錶中如果要查詢的目標在第n個節點,就必須從頭開始搜尋,搜尋n個節點如果這個n很大那麼查詢的效率就會很低。

在hash表中,只需要對搜尋目標進行hash運算根據上面的公式得到hash bucket的編號即可。

其次鍊錶需要使用迴圈逐個搜尋,hash表沒有迴圈。鍊錶演算法的複雜度是o(n),而hash演算法的複雜度是o(1)。

雜湊演算法(Hash函式)簡單介紹

雜湊演算法的定義和原理 將任意長度的二進位制值串對映為固定長度的二進位制值串,這個對映的規則,就是雜湊演算法。而通過原始資料對映之後得到的二進位制值串就是雜湊值。設計乙個優秀的雜湊演算法,需要滿足下面幾點要求 a.從雜湊值不能反向推導出原始資料 所以雜湊演算法也叫單向雜湊演算法 b.對輸入的資料比較...

Hash 雜湊介紹

1 雜湊概念 在順序結構以及平衡樹中,元素關鍵碼與其儲存位置之間沒有對映關係,想要查詢乙個元素必須要關鍵碼之間進行多次比較,順序查詢的時間複雜度為o n 在平衡二叉搜尋樹中查詢為o logn 搜尋的效率取決於關鍵碼的比較次數 但是有沒有一種理想的搜尋方法可以實現不用關鍵碼之間的對比從而找到乙個元素呢...

hash簡單介紹

hash也稱 雜湊 是一種基於對映關係的儲存方式,將任意長度的二進位制值輸出為固定長度的較小的二進位制值,這種輸出的小的固定長度的值為hash值 1.雜湊技術是在關鍵字key與儲存位置之間建立對應的關係,計算得到儲存們置,建立這種關係的函式就是雜湊函式f,儲存位置為f key 2.每個關鍵字對應唯一...