In-Memory:Hash Index

来源:http://www.cnblogs.com/ljhdo/archive/2017/01/09/5762701.html
-Advertisement-
Play Games

SQL Server 2016支持哈希查找,用戶可以在記憶體優化表(Memory-Optimized Table)上創建Hash Index,使用Hash 查找演算法,實現數據的極速查找。在使用上,Hash Index 和B-Tree索引的區別是:Hash Index 是無序查找,Index Key必須 ...


SQL Server 2016支持哈希查找,用戶可以在記憶體優化表(Memory-Optimized Table)上創建Hash Index,使用Hash 查找演算法,實現數據的極速查找。在使用上,Hash Index 和B-Tree索引的區別是:Hash Index 是無序查找,Index Key必須全部作為Filter,而B-Tree索引是有序查找,不需要Index Key都作為Filter,只需要前序欄位存在即可;在存儲結構上,Hash Index使用Hash Table實現,存在Hash 衝突,而B-Tree索引的結構是平衡樹,存在頁拆分,碎片問題。

一,Hash 查找演算法

在《數據結構》課程中,Hash查找的演算法是:以關鍵字k為自變數,通過一個映射函數h,計算出對應的函數值y=h(k)(y稱作哈希值,或哈希地址),根據函數值y,將關鍵字k存儲在數組(bucket數組)所指向的鏈表中。在進行哈希查找時,根據關鍵字,使用相同的函數h計算哈希地址h(k),然後直接定址相應的Hash bucket,直接到對應的鏈表中取出數據。因此,Hash 查找演算法的數據結構由Hash Bucket數組,映射函數f和數據鏈表組成,通常將Bucket數組和數據鏈表稱作Hash Table,如圖,Hash Table由5個buckets和7個數據結點組成:

哈希查找的時間複雜度是O(n/m),n是指數據結點的數量,m是bucket的數量,在理想情況下,Hash Bucket足夠多,Hash函數不產生重覆的Hash Value,哈希查找的時間複雜度最優到達O(1),但是,在實際應用中,哈希函數有一定的幾率出現重覆的哈希地址,產生哈希衝突,時間複雜度會低於O(n/m);在最差的情況下,時間複雜度是O(n)。

二,Hash Index的結構

Hash Index使用Hash查找演算法實現,SQL Server內置Hash函數,用於所有的Hash Index,因此,Hash Index就是Hash Table,由Hash Buckets數組和數據行鏈表組成。創建Hash Index時,通過Hash函數計算Index Key的Hash地址,Hash地址不同的數據行指向不同的Bucket,Hash地址相同的數據行指向相同的Bucket,如果多個數據行的Hash地址相同,都指向同一個Bucket,那麼將這些數據行鏈接在一起,組成一個鏈表。

A hash index consists of an array of pointers, and each element of the array is called a hash bucket. The index key column in each row has a hash function applied to it, and the result of the function determines which bucket is used for that row. All key values that hash to the same value (have the same result from the hash function) are accessed from the same pointer in the hash index and are linked together in a chain. When a row is added to the table, the hash function is applied to the index key value in the row. If there is duplication of key values, the duplicates will always generate the same function result and thus will always be in the same chain.

舉例說明,假定哈希函數是h(k)=Length(k),用於計算Index Key的字元個數,在記憶體優化表(Name,City)上創建Hash Index,Index ptr指向鏈表中的下一個數據行,如果沒有下一個數據行,那麼該指針為NULL:

1,以Name為Index Key創建Hash Index

第一個數據行的Name是“Jane”,HashValue是4,將該行數據映射到下標為4的Bucket中(Bucket數組的第五個元素),由於該數據行是第一個數據結點,Index ptr為NULL。

 

第二個數據行,Name值是“Greg”,HashValue是4,映射到下標為4的Bucket中,和第一個數據行鏈接在一起,組成一個鏈表(Chain),插入數據結點時,使用頭部插入法,新的數據節點作為頭結點,將頭節點的Index ptr(next pointer)指針指向數據鏈表的第一個數據結點,如圖,新的頭結點“Greg”的Index ptr指向第一個數據行“Jane”。

 

2,創建第二個Hash Index,以City為Index Key

當創建第二個Hash Index時,每個數據行結構中包含兩個Index ptr指針,都用於指向下一個數據節點(Next Pointer):第一個Index ptr用於Index Key為Name的Hash Index,當出現相同的Hash Value時,該指針指向鏈表中下一個數據行,使數據行鏈接到一起組成鏈表;第二個Index ptr用於Index Key為City的Hash Index,指向鏈表中下一個數據行。

因此,當創建一個新的Hash Index時,在數據結構上,SQL Server需要創建Hash Buckets數組,併在每個數據行中增加一個Index ptr欄位,根據Index Key為Index ptr賦值,組成一個新數據行鏈表,但是數據行的數量保持不變。

3,Hash 函數

在創建Hash Index時,不需要編寫Hash 函數,SQL Server內置Hash函數:

  • 內置的Hash函數產生的HashValue是隨機和不可預測的,適用於所有的Hash Index;
  • 內置的Hash函數是確定性的,相同的Index Key總是映射到相同的Bucket;
  • 有一定的幾率,多個Index Key會映射到相同的bucket中;
  • 哈希函數是均衡的,產生的Hash Value服從泊松分佈;

泊松分佈不是均勻分佈,Index Key不是均勻地分佈在Hash bucket數組中。例如,有n個Hash Bucket,n個不同的Index Key,泊松分佈產生的結果是:大約有1/3的Hash Bucket是空的,大約1/3的Hash bucket存儲一個Index Key,剩下1/3的Hash Buckets存儲2個Index Key。

4,Hash Index的鏈表長度

不同的Index Key,經過hash函數映射之後,可能生成相同的Hash Value,映射到相同的bucket中,產生 Hash 衝突。Hash演算法,將映射到相同Bucket的多個Index Key組成一個鏈表,鏈表越長,Hash Index查找性能越差。

在DMV:sys.dm_db_xtp_hash_index_stats (Transact-SQL)中,表示Hash Index鏈長的欄位有:avg_chain_length 和 max_chain_length ,鏈長應保持在2左右;鏈長過大,表明太多的數據行被映射到相同的Bucket中,這會顯著影響Hash Index的查詢性能,導致鏈長過大的原因是:

  • 總的Bucket數量少,導致不同的Index Key映射到相同的Bucket上;
  • 如果空的Bucket數量大,但鏈長過大,這說明,Hash Index存在大量重覆的Index Key;相同的Index Key被映射到相同的bucket;

三,創建Hash Index

在記憶體優化表上創建Index,不能使用Create Index命令,SQL Server 2016支持兩種方式創建索引:

1,在創建記憶體優化表時創建Hash Index

創建Hash Index的語法是:

INDEX index_name [ NONCLUSTERED ] HASH WITH (BUCKET_COUNT = bucket_count)  

創建Hash Index的示例:

--create memory optimized table
create table [dbo].[products]
(
    [ProductID] [bigint] not null,
    [Name] [varchar](64) not null,
    [Price] decimal(10,2) not null,
    [Unit] varchar(16) not null,
    [Description] [varchar](max) null,
    constraint [PK__Products_ProductID] primary key nonclustered hash ([ProductID])with (bucket_count=2000000)
    ,index idx_Products_Price  nonclustered([Price] desc)
    ,index idx_Products_Unit nonclustered hash(Unit) with(bucket_count=40000)
)
with(memory_optimized=on,durability= schema_and_data)
go
View Code

2,使用Alter Table命令創建Hash Index

alter table [dbo].[products]
add index hash_idx_Products_Name nonclustered hash(name)with(bucket_count=40000);

四,Hash Index的特點

總結Hash Index的特點:

  • Hash Index使用Hash Table組織Index 結構,每一個數據節點都包含一個指針,指向數據行的記憶體地址;
  • Hash Index是無序的,適合做單個數據行的Index Seek;
  • 只有當Hash Index Key全部出現在Filter中,SQL Server才會使用Hash Index Seek操作查找相應的數據行,如果缺失任意一個Index Column,那麼SQL Server都會執行Full Table Scan以獲取符合條件的數據行。例如,創建Hash Index時指定N個column,那麼SQL Server對這N個column計算Hash  Value,映射到相應的bucket上,所以,只有當這N個Column都存在時,才能定位到對應的bucket,進而查找相應的數據結點;
Hash indexes require values for all index key columns in order to compute the hash value, and locate the corresponding rows in the hash table. Therefore, if a query includes equality predicates for only a subset of the index keys in the WHERE clause, SQL Server cannot use an index seek to locate the rows corresponding to the predicates in the WHERE clause.

 

參考文檔:

Hash Indexes

Guidelines for Using Indexes on Memory-Optimized Tables

Troubleshooting Common Performance Problems with Memory-Optimized Hash Indexes

Linux內核中的hash與bucket


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 大綱簡介 安裝前,先簡單介紹一下memcached。 memcached是一個免費、開源、高性能的分散式緩存。設計memcached的初衷是為了加快web應用程式,減少DB負載。 安裝要求:支持大多數linux和基於BSD的系統,官方沒有給出windows版本,但是網上有memcached for ...
  • 本篇將去探索twemproxy源碼的主幹流程,想來對於想要開始啃這份優秀源碼生肉的童鞋會有不小的幫助。這裡我們首先要找到 twemproxy正確的打開方式——twemproxy的文件結構,接著介紹twemproxy程式代碼框架,最後介紹twemproxy程式的主幹流程。主幹流程是本章節的重中之重。這 ...
  • 本文出處:http://www.cnblogs.com/wy123/p/6262800.html 在考慮重編譯T-SQL(或者存儲過程)的時候,有兩種方式可以實現強制重編譯(前提是忽略導致重編譯的其他因素的情況下,比如重建索引,更新統計信息等等), 一是基於WITH RECOMPILE的存儲過程級別 ...
  • 寫在前面 在QQ群,微信群,論壇中經常幫助使用SQL Server資料庫的朋友解決問題,但是有一些最常見最基本的問題,每天都有人問,回答多了也不想再解答了,索性把這些問題整理一下,再有人問到直接發鏈接。 一時想法而寫這篇文章,問題可能不全面,後續會一直更新。 基礎問題收集 資源下載 描述:XX版本數 ...
  • 一、HBase的特點是什麼 1.HBase一個分散式的基於列式存儲的資料庫,基於hadoop的hdfs存儲,zookeeper進行管理。 2.HBase適合存儲半結構化或非結構化數據,對於數據結構欄位不夠確定或者雜亂無章很難按一個概念去抽取的數據。 3.HBase為null的記錄不會被存儲. 4.基 ...
  • twemproxy背景 在業務量劇增的今天,單台高速緩存伺服器已經無法滿足業務的需求, 而相較於大容量SSD數據存儲方案,緩存具備速度和成本優勢,但也存在數據安全性的挑戰。為此搭建一個高速緩存伺服器集群來進行分散式存儲是十分必要的。 目前主流的高速緩存伺服器是redis和memchache。而twe ...
  • 本文將介紹閃回原理,給出筆者的實戰經驗,並對現存的閃回工具作比較。 DBA或開發人員,有時會誤刪或者誤更新數據,如果是線上環境並且影響較大,就需要能快速回滾。傳統恢復方法是利用備份重搭實例,再應用去除錯誤sql後的binlog來恢複數據。此法費時費力,甚至需要停機維護,並不適合快速回滾。也有團隊利用 ...
  • 本文轉自:樂沙彌的世界 對於物理損壞的數據塊,我們可以通過RMAN塊介質恢復(BLOCK MEDIA RECOVERY)功能來完成受損塊的恢復,而不需要恢復整個資料庫或所有文件來修複這些少量受損的數據塊。恢復整個資料庫或數據文件那不是大炮用來打蚊子,有點不值得!但前提條件是你得有一個可用的RMAN備 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...