您的位置:新葡亰496net > 网络数据库 > 哈希索引原理,内存优化表的DMV

哈希索引原理,内存优化表的DMV

发布时间:2019-09-15 20:18编辑:网络数据库浏览(189)

    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索引的结构是平衡树,存在页拆分,碎片问题。

    SQL Server 在执行查询时,自动将活动的相关信息保存在内存中,这些活动信息称作DMV(Dynamic Management View),DMV记录SQL Server实例级别上的活动信息。由于DMV使用内存作为存储媒介,在读取DMV时,不需要IO操作,读写数据速度极快,不会对Server产生压力,并且DMV直接存储在服务器的内存中,能够及时、精确地反映系统性能的最新状态。

    SQL Server 在执行查询时,自动将活动的相关信息保存在内存中,这些活动信息称作DMV(Dynamic Management View),DMV记录SQL Server实例级别上的活动信息。由于DMV使用内存作为存储媒介,在读取DMV时,不需要IO操作,读写数据速度极快,不会对Server产生压力,并且DMV直接存储在服务器的内存中,能够及时、精确地反映系统性能的最新状态。

    SQL Server2014 哈希索引原理

    翻译自

    跟哈希 join,哈希 聚合的原理一样,了解哈希索引的原理也会同时明白哈希 join和哈希 聚合的原理

     

    SQL Server 2014推出的的新索引类型叫做 hash index。介绍hash index之前一定要介绍哈希函数这样会让大家更明白哈希索引的原理

    当一个key-value键值对传递给一个哈希函数的时候,经过哈希函数的计算之后,根据结果会把key-value键值对放在合适的hash buckets(哈希存储桶)里

     

    举个栗子

    我们假设对10取模( % 10 )就是哈希函数。如果key-value键值对的key是1525 ,传递到哈希函数,那么1525 会存放在第五个bucket里

    因为5 as 1525 % 10 = 5。

    同样,537 会存放在第七个bucket ,2982 会存放在第二个bucket ,依次类推

     

    同样,在hash index里面,哈希索引列会被传递给哈希函数做匹配(类似于java里面的HashMap的Map操作),匹配成功之后,

    索引列会被存储在匹配到的hash bucket里面的表里,这个表里会有实际的数据行指针,再根据实际的数据行指针查找对应的数据行。

     

    概括来说,要查找一行数据或者处理一个where子句,SQL Server引擎需要做下面几件事

    1、根据where条件里面的参数生成合适的哈希函数

    2、索引列进行匹配,匹配到对应hash bucket,找到对应hash bucket意味着也找到了对应的数据行指针(row pointer)

    3、读取数据

     

    哈希索引比起B树索引简单,因为它不需要遍历B树,所以访问速度会更快

    图片 1

     

    哈希函数和相应语法的例子

    CREATE TABLE dbo.HK_tbl
        (
          [ID] INT IDENTITY(1, 1)
                   NOT NULL
                   PRIMARY KEY NONCLUSTERED HASH WITH ( BUCKET_COUNT = 100000 ) ,
          [Data] char(32) COLLATE Latin1_General_100_BIN2
                          NULL ,
          [dt] datetime NOT NULL,
        )
        WITH (
             MEMORY_OPTIMIZED =
             ON,
             DURABILITY =
             SCHEMA_AND_DATA);
    

     

    在SQL Server 2014里面,内存优化表创建完之后就不能再加哈希索引了,但是在 SQL Server 2016 里支持表创建完之后添加哈希索引,不过

    添加哈希索引是一个离线操作。

     

     

    哈希索引的Bucket 数量

    ( BUCKET_COUNT = 100000 )定义了哈希索引能够使用的BUCKET数量,这个Bucket 是固定的并且由用户指定Bucket 数量,

    而不是执行查询的时候由SQL Server决定生成的Bucket 数量。BUCKET数量总是2的次方的四舍五入( 1024, 2048, 4096 etc..)

    BUCKET_COUNT 的数量一定要设置合适,否则哈希冲突太多,反而性能会下降

     

     

    SQL Server2014的哈希索引其实跟MySQL的自适应哈希索引原理其实差不多,都是为了摆脱B树的束缚,使查找效率更快

    How does a relational database work这篇文章也有描述hash join的原理,大家可以看一下

    图片 2

    图片 3

     

     

    相关文章

    MySQL Adaptive hash index

    java HashMap那点事

    How does a relational database work

     

    如有不对的地方,欢迎大家拍砖o(∩_∩)o 

    一,Hash 查找算法

    一,使用DMV的注意事项

    一,使用DMV的注意事项

    在《数据结构》课程中,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个数据结点组成:

    1,确定数据保存的时间

    1,确定数据保存的时间

    图片 4

    内存是易失性的存储媒介,一旦SQL Server实例重启,DMV存储的信息将全部重置。在使用DMV时,首先需要检查这些信息在内存中保存了多长时间,以确定DMV数据的可用性。如果SQL Server仅仅运行很短的一段时间,那么对DMV数据进行统计和分析是不合适的,这些数据不是SQL Server 实例真实工作负载的数据样本。SQL Server运行的时候越长,DMV中保存的信息就越多(当然,DMV非常小,不会对内存造成压力),利用DMV分析就越准确。

    内存是易失性的存储媒介,一旦SQL Server实例重启,DMV存储的信息将全部重置。在使用DMV时,首先需要检查这些信息在内存中保存了多长时间,以确定DMV数据的可用性。如果SQL Server仅仅运行很短的一段时间,那么对DMV数据进行统计和分析是不合适的,这些数据不是SQL Server 实例真实工作负载的数据样本。SQL Server运行的时候越长,DMV中保存的信息就越多(当然,DMV非常小,不会对内存造成压力),利用DMV分析就越准确。

    哈希查找的时间复杂度是O(n/m),n是指数据结点的数量,m是bucket的数量,在理想情况下,Hash Bucket足够多,Hash函数不产生重复的Hash Value,哈希查找的时间复杂度最优到达O(1),但是,在实际应用中,哈希函数有一定的几率出现重复的哈希地址,产生哈希冲突,时间复杂度会低于O(n/m);在最差的情况下,时间复杂度是O(n)。

    2,DMV使用的内存有限

    2,DMV使用的内存有限

    二,Hash Index的结构

    DMV能够使用的内存容量有限,这使得DMV只能存储有限数量的数据。如果SQL Server运行了很长世间,SQL Server Engine会将DMV的一些老数据覆盖。

    DMV能够使用的内存容量有限,这使得DMV只能存储有限数量的数据。如果SQL Server运行了很长世间,SQL Server Engine会将DMV的一些老数据覆盖。

    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,那么将这些数据行链接在一起,组成一个链表。

    二,查看内存优化表的DMV

    二,查看内存优化表的DMV

    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.

    SQL Server创建一些DMV,用于追踪内存优化表的活动信息,在内存优化表的DMV中,有两个对象ID(Object ID):

    SQL Server创建一些DMV,用于追踪内存优化表的活动信息,在内存优化表的DMV中,有两个对象ID(Object ID):

    举例说明,假定哈希函数是h(k)=Length(k),用于计算Index Key的字符个数,在内存优化表(Name,City)上创建Hash Index,Index ptr指向链表中的下一个数据行,如果没有下一个数据行,那么该指针为NULL:

    • xtp_object_id 是内部的内存优化表(Internal Memory-Optimized Table)的ID,在对象的整个生命周期中,该ID可变;
    • object_id 是User Table的ID,唯一标识该User Table,在对象的整个生命周期中,该ID不变;
    • xtp_object_id 是内部的内存优化表(Internal Memory-Optimized Table)的ID,在对象的整个生命周期中,该ID可变;
    • object_id 是User Table的ID,唯一标识该User Table,在对象的整个生命周期中,该ID不变;

    图片 5

    xtp_object_id 是内部的内存优化表的ID(Internal Memory-Optimized Table),每一个User Table都对应一个或多个Internal Table:

    xtp_object_id 是内部的内存优化表的ID(Internal Memory-Optimized Table),每一个User Table都对应一个或多个Internal Table:

    1,以Name为Index Key创建Hash Index

    • 一个Interal Table用于存储核心数据(Core Data);
    • 其他的Internal Table 用于存储临时数据,Columnstore Index ,Off-Row(Lob);
    • 详细信息,请阅读DMV: sys.memory_optimized_tables_internal_attributes
    • 一个Interal Table用于存储核心数据(Core Data);
    • 其他的Internal Table 用于存储临时数据,Columnstore Index ,Off-Row(Lob);
    • 详细信息,请阅读DMV: sys.memory_optimized_tables_internal_哈希索引原理,内存优化表的DMV。attributes

    第一个数据行的Name是“Jane”,HashValue是4,将该行数据映射到下标为4的Bucket中(Bucket数组的第五个元素),由于该数据行是第一个数据结点,Index ptr为NULL。

    1,查看内存优化表占用的物理内存

    1,查看内存优化表占用的物理内存

     图片 6

    --memory usage
    select tms.object_id
        ,object_schema_name(tms.object_id) '.' object_name(tms.object_id) as table_name
        ,(tms.memory_allocated_for_indexes_kb tms.memory_allocated_for_table_kb)/1024 as total_allocated_mb
        ,tms.memory_allocated_for_table_kb/1024 as table_allocated_mb
        ,tms.memory_used_by_table_kb/1024 as table_used_mb
        ,(tms.memory_allocated_for_table_kb-tms.memory_used_by_table_kb)/1024 as table_unused_mb
        ,tms.memory_allocated_for_indexes_kb/1024 as index_allocated_mb
        ,tms.memory_used_by_indexes_kb/1024 as index_used_mb
        ,(tms.memory_allocated_for_indexes_kb-tms.memory_used_by_indexes_kb)/1024 as index_unused_mb
    from sys.dm_db_xtp_table_memory_stats tms
    where tms.object_id>0
    
    --memory usage
    select tms.object_id
        ,object_schema_name(tms.object_id) '.' object_name(tms.object_id) as table_name
        ,(tms.memory_allocated_for_indexes_kb tms.memory_allocated_for_table_kb)/1024 as total_allocated_mb
        ,tms.memory_allocated_for_table_kb/1024 as table_allocated_mb
        ,tms.memory_used_by_table_kb/1024 as table_used_mb
        ,(tms.memory_allocated_for_table_kb-tms.memory_used_by_table_kb)/1024 as table_unused_mb
        ,tms.memory_allocated_for_indexes_kb/1024 as index_allocated_mb
        ,tms.memory_used_by_indexes_kb/1024 as index_used_mb
        ,(tms.memory_allocated_for_indexes_kb-tms.memory_used_by_indexes_kb)/1024 as index_unused_mb
    from sys.dm_db_xtp_table_memory_stats tms
    where tms.object_id>0
    

    第二个数据行,Name值是“Greg”,HashValue是4,映射到下标为4的Bucket中,和第一个数据行链接在一起,组成一个链表(Chain),插入数据结点时,使用头部插入法,新的数据节点作为头结点,将头节点的Index ptr(next pointer)指针指向数据链表的第一个数据结点,如图,新的头结点“Greg”的Index ptr指向第一个数据行“Jane”。

    2,查看内存消费者(Memory Consumer)

    2,查看内存消费者(Memory Consumer)

     图片 7

    每一个MOT都有单独的Memory Heap,称作VarHeap,是一个Memory Consumer,SQL Server从VarHeap中为MOT的数据分配内存空间。varheap是可变大小的堆数据结构,能够收缩和增长。VarHeap是由固定数量的Allocation Unit组成的集合。Allocation Unit用于分配特定大小的Page,Page的大小是不固定的,最常见的Page Size是64KB。

    每一个MOT都有单独的Memory Heap,称作VarHeap,是一个Memory Consumer,SQL Server从VarHeap中为MOT的数据分配内存空间。varheap是可变大小的堆数据结构,能够收缩和增长。VarHeap是由固定数量的Allocation Unit组成的集合。Allocation Unit用于分配特定大小的Page,Page的大小是不固定的,最常见的Page Size是64KB。

    2,创建第二个Hash Index,以City为Index Key

    VarHeap用于Table Row 和 Bw-Tree Index。每一个LOB列(使用max指定大小)都有自己独立的VarHeap。在创建MOT时,SQL Server决定哪些column存储在Table的VarHeap中,哪些column存储在自己独立的VarHeap中。

    VarHeap用于Table Row 和 Bw-Tree Index。每一个LOB列(使用max指定大小)都有自己独立的VarHeap。在创建MOT时,SQL Server决定哪些column存储在Table的VarHeap中,哪些column存储在自己独立的VarHeap中。

    当创建第二个Hash Index时,每个数据行结构中包含两个Index ptr指针,都用于指向下一个数据节点(Next Pointer):第一个Index ptr用于Index Key为Name的Hash Index,当出现相同的Hash Value时,该指针指向链表中下一个数据行,使数据行链接到一起组成链表;第二个Index ptr用于Index Key为City的Hash Index,指向链表中下一个数据行。

    Hash Index 使用另外一个Memory Consumer,称作Hash。

    Hash Index 使用另外一个Memory Consumer,称作Hash。

    因此,当创建一个新的Hash Index时,在数据结构上,SQL Server需要创建Hash Buckets数组,并在每个数据行中增加一个Index ptr字段,根据Index Key为Index ptr赋值,组成一个新数据行链表,但是数据行的数量保持不变。

    图片 8图片 9

    图片 10图片 11

    图片 12

    select
        object_schema_name(mc.object_id) '.' object_name(mc.object_id) as table_name 
        ,a.xtp_object_id
        ,a.type_desc as xtp_object_type
        ,iif(a.minor_id=0,'User Table','Off-Row Column:' col_name(a.object_id,a.minor_id)) as xtp_object
        ,mc.memory_consumer_id as consumer_id
        ,mc.memory_consumer_type_desc as consumer_type
        ,mc.memory_consumer_desc as consumer_desc
        ,i.name as index_name
        ,i.type_desc as index_type_desc
        ,mc.allocated_bytes/1024/1024 as allocated_mb
        ,mc.used_bytes/1024/1024 as used_mb
        ,mc.allocation_count
    from sys.dm_db_xtp_memory_consumers mc
    inner join sys.memory_optimized_tables_internal_attributes a
        on mc.object_id=a.object_id
            and mc.xtp_object_id=a.xtp_object_id
    left join sys.indexes i 
        on mc.object_id=i.object_id
            and mc.index_id=i.index_id
    where mc.object_id=object_id('[influencer].[Influencers]')
    
    select
        object_schema_name(mc.object_id) '.' object_name(mc.object_id) as table_name 
        ,a.xtp_object_id
        ,a.type_desc as xtp_object_type
        ,iif(a.minor_id=0,'User Table','Off-Row Column:' col_name(a.object_id,a.minor_id)) as xtp_object
        ,mc.memory_consumer_id as consumer_id
        ,mc.memory_consumer_type_desc as consumer_type
        ,mc.memory_consumer_desc as consumer_desc
        ,i.name as index_name
        ,i.type_desc as index_type_desc
        ,mc.allocated_bytes/1024/1024 as allocated_mb
        ,mc.used_bytes/1024/1024 as used_mb
        ,mc.allocation_count
    from sys.dm_db_xtp_memory_consumers mc
    inner join sys.memory_optimized_tables_internal_attributes a
        on mc.object_id=a.object_id
            and mc.xtp_object_id=a.xtp_object_id
    left join sys.indexes i 
        on mc.object_id=i.object_id
            and mc.index_id=i.index_id
    where mc.object_id=object_id('[influencer].[Influencers]')
    

    3,Hash 函数

    View Code

    View Code

    在创建Hash Index时,不需要编写Hash 函数,SQL Server内置Hash函数:

    引用:SQL Server In-Memory OLTP Internals for SQL Server 2016

    引用:SQL Server In-Memory OLTP Internals for SQL Server 2016

    • 内置的Hash函数产生的HashValue是随机和不可预测的,适用于所有的Hash Index;
    • 内置的Hash函数是确定性的,相同的Index Key总是映射到相同的Bucket;
    • 有一定的几率,多个Index Key会映射到相同的bucket中;
    • 哈希函数是均衡的,产生的Hash Value服从泊松分布;

    The varheaps are used for both table rows and Bw-tree indexes. (Hash indexes are the only structure used with memory-optimized tables that uses a different memory consumer.) In addition, each LOB, column (specified with the MAX qualifier in the datatype definition) has its own varheap. As mentioned earlier, SQL Server 2016 also supports large columns similar to the row-overflow columns for disk-based tables. For memory-optimized tables, SQL Server will decide when the table is created which of your variable length columns will be stored in the table’s varheap and which will be stored as overflow data and have their own varheap. You can think of LOB and row-overflow columns as being stored in their own internal tables.

    The varheaps are used for both table rows and Bw-tree indexes. (Hash indexes are the only structure used with memory-optimized tables that uses a different memory consumer.) In addition, each LOB, column (specified with the MAX qualifier in the datatype definition) has its own varheap. As mentioned earlier, SQL Server 2016 also supports large columns similar to the row-overflow columns for disk-based tables. For memory-optimized tables, SQL Server will decide when the table is created which of your variable length columns will be stored in the table’s varheap and which will be stored as overflow data and have their own varheap. You can think of LOB and row-overflow columns as being stored in their own internal tables.

    泊松分布不是均匀分布,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。

    You can examine the metadata for each varheap (and the other memory consumers) in a DMV called sys.dm_db_xtp_memory_consumers. Each memory-optimized table has a row in this view for each varheap and for each hash index. (We will see one more type of memory consumer, called HkCS Allocator, in the section on columnstore indexes on memory-optimized tables.) If we join this DMV with the catalog view called sys.memory_optimized_tables_internal_attributes we can see which varheap belongs to a specific column. Each user table has a unique object_id and xtp_object_id value which is used by all the indexes. Each additional varheap, for the row_overflow and LOB columns will have its own xtp_object_id. Note that if an object is altered, its xtp_object_id will change, but its object_id will not. 

    You can examine the metadata for each varheap (and the other memory consumers) in a DMV called sys.dm_db_xtp_memory_consumers. Each memory-optimized table has a row in this view for each varheap and for each hash index. (We will see one more type of memory consumer, called HkCS Allocator, in the section on columnstore indexes on memory-optimized tables.) If we join this DMV with the catalog view called sys.memory_optimized_tables_internal_attributes we can see which varheap belongs to a specific column. Each user table has a unique object_id and xtp_object_id value which is used by all the indexes. Each additional varheap, for the row_overflow and LOB columns will have its own xtp_object_id. Note that if an object is altered, its xtp_object_id will change, but its object_id will not. 

    图片 13

    3,Hash Index的链表长度

    3,Hash Index的链表长度

    4,Hash Index的链表长度

    对于Hash Index,表示链长的字段有:avg_chain_length 和 max_chain_length ,链长应保持在2左右;链长过大,表明太多的数据行被映射到相同的Bucket中,这会显著影响DML操作的性能。

    对于Hash Index,表示链长的字段有:avg_chain_length 和 max_chain_length ,链长应保持在2左右;链长过大,表明太多的数据行被映射到相同的Bucket中,这会显著影响DML操作的性能。

    不同的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;
    • 详细信息,请阅读:sys.dm_db_xtp_hash_index_stats (Transact-SQL);
    • 总的Bucket数量少,导致不同的Index Key映射到相同的Bucket上;
    • 如果空的Bucket数量大,但链长过大,这说明,Hash Index存在大量重复的Index Key;相同的Index Key被映射到相同的bucket;
    • 详细信息,请阅读:sys.dm_db_xtp_hash_index_stats (Transact-SQL);
    • 总的Bucket数量少,导致不同的Index Key映射到相同的Bucket上;
    • 如果空的Bucket数量大,但链长过大,这说明,Hash Index存在大量重复的Index Key;相同的Index Key被映射到相同的bucket;

    4,事务

    4,事务

    三,创建Hash Index

    在访问MOT时,有两种类型事务ID,在事务中,访问MOT和访问DBT的事务是独立的:

    在访问MOT时,有两种类型事务ID,在事务中,访问MOT和访问DBT的事务是独立的:

    在内存优化表上创建Index,不能使用Create Index命令,SQL Server 2016支持两种方式创建索引:

    • xtp_transaction_id:是访问MOT的事务ID;
    • transaction_id:是访问DBT的事务ID,0表示事务没有访问MOT;
    • 详细信息,请阅读:sys.dm_db_xtp_transactions (Transact-SQL)
    • xtp_transaction_id:是访问MOT的事务ID;
    • transaction_id:是访问DBT的事务ID,0表示事务没有访问MOT;
    • 详细信息,请阅读:sys.dm_db_xtp_transactions (Transact-SQL)

    1,在创建内存优化表时创建Hash Index

     查看当前数据库中活跃事务的信息:

     查看当前数据库中活跃事务的信息:

    创建Hash Index的语法是:

    select t.xtp_transaction_id
        ,t.transaction_id
        ,t.session_id
        ,t.begin_tsn
        ,t.end_tsn
        ,t.state_desc
        ,t.result_desc
    from sys.dm_db_xtp_transactions t
    
    select t.xtp_transaction_id
        ,t.transaction_id
        ,t.session_id
        ,t.begin_tsn
        ,t.end_tsn
        ,t.state_desc
        ,t.result_desc
    from sys.dm_db_xtp_transactions t
    
    INDEX index_name [ NONCLUSTERED ] HASH WITH (BUCKET_COUNT = bucket_count)  
    

     

     

    创建Hash Index的示例:

    参考文档:

    参考文档:

    图片 14图片 15

    Baselining with SQL Server Dynamic Management Views

    Baselining with SQL Server Dynamic Management Views

    --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
    

    Memory-Optimized Table Dynamic Management Views (Transact-SQL)

    Memory-Optimized Table Dynamic Management Views (Transact-SQL)

    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.aspx)

    Guidelines for Using Indexes on Memory-Optimized Tables.aspx)

    Troubleshooting Common Performance Problems with Memory-Optimized Hash Indexes.aspx)

    Linux内核中的hash与bucket

    本文由新葡亰496net发布于网络数据库,转载请注明出处:哈希索引原理,内存优化表的DMV

    关键词: