SQL Server In-Memory OLTP Internals for SQL Server 2016
这份白皮书是在上一份《SQL Server In-Memory OLTP Internals Overview》基础上的,很多东西都是一样的不再介绍,只介绍不相同的部分。

行和索引存储

Range索引

的时候还是不支持的。Range index 使用bwtree数据结构。Bwtree和btree一样有叶子结点和中间节点。最重要的不通点是,bwtree page指针是一个逻辑的page id,而不是物理的page no。PID表示mapping table 上的位置,mapping table把PID和物理内存地址关联。Bwtree的index page是从来不更新的,而是增加一个新的,然后让mapping table的相同PID指向一个不同的物理内存地址。

具体的bwtree的算法可以看:http://www.cnblogs.com/Amaranthus/p/4375331.html

列存储索引

列存储索引基本结构

SQL Server 2016内存优化表支持聚集的列存储索引。列存储索引是高复合的索引,并不是由行来组织,而是用列来组织的。行被分为多个组,一个组最多可以有2^20行,然后把某一列的数据放入行组中,不会去管剩下的行。

每个行组,SQL Server都会使用Vertipaq压缩算法,重新编码和排列行组中的顺序来打到最有的压缩效果。每个行组中的列都是独立保存的,这个结构称之为段(segment),每个段都是一个LOB,保存在LOB的分配段元中。段是数据读写的基本单元,如图,表示吧一组多个索引列转化为几个段

个段。

万行),SQL Server会吧这些行转化为新的压缩的行组。

内存优化表中聚集列存储索引和内存优化表的非聚集索引是分开保存的,是数据的一个副本。实际上,内存优化表的聚集列存储索引你可以理解为,保存了所有列的非聚集列存储索引。因为数据是高效压缩的,因此开销比较少。因为类存储索引可以压缩到原始数据的10%,因此开销也只有10%。

所有的类存储索引段都是在内存中的。为了恢复的目的,每个行组在内存优化文件组中都保存成一个独立的文件类型为LARGE DATA,在文件中对于某个行组,所有的段都是存放在一起的。SQL Server也维护了一个指针,指向每个段并且可以访问这个段,特别是访问了部分列的时候。这个部分会在下面CHECKPOINT FILES的时候介绍。新的行会被以列存储索引保存,但是并不会马上加入到压缩行组中,新的行只能使用内存优化表的其他索引来访问。如图,新的行和整个表分开维护的。你可以认为这些行是“delta rowgroup”和磁盘表的Delta Store类似,但是这些行是内存优化表的一部分,但是不是技术上的列存储索引的一部分。实际上是课件的delta rowgroup

个varheap,一个用于压缩行组,另外一个用来保存新行,可以让SQL Server快速识别哪些行还没有进入压缩段,这些行也在可见的delta rowgroup中。

个操作:

  1. 行会被复制到一个或者多个行组,每个段都会被压缩转化变成聚集列存储索引的一部分。
  2. 行会从特定的内存分配器移到常规的内存存储。

万行那么这些行还是会被留在原来的地方。

万才会被压缩到常规的列存储索引行组中。

当行被转换到压缩rowgroup之后,所有删除的行都会被放到Delete Rows表中,和磁盘表的聚集列存储索引。当行多的时候查询会很没有效率。这种情况下重组列存储索引并没有什么用,除非删除并且重建索引。一旦rowgroup中90%的行被删除,剩下的10%会自动被插入到未压缩的varheap,在内存优化表的Delta rowgroup中。Rowgroup的存储会被进行垃圾回收。

Note:
前面提到的,如果内存优化表有任何LOB或者溢出列,列存储索引不能在上面被创建。因为最大的行不能超过8060字节。另外一旦内存优化表有一个列存储索引,就不能使用alter table操作。需要先删除列存储索引,alter,然后再创建列存储索引。

分钟。

USE master;
GO
SET NOCOUNT ON;
GO
DROP DATABASE IF EXISTS IMDB;
GO
CREATE DATABASE IMDB;
GO
ALTER DATABASE IMDB
    ADD FILEGROUP IMDB_mod_FG
    CONTAINS MEMORY_OPTIMIZED_DATA;
GO
ALTER DATABASE IMDB
    ADD FILE (   NAME = 'IMDB_mod' ,
                 FILENAME = 'c:\HKData\IMDB_mod'
             )
    TO FILEGROUP IMDB_mod_FG;
GO
USE IMDB;
GO
DROP TABLE IF EXISTS dbo.OrderDetailsBig;
GO
CREATE TABLE dbo.OrderDetailsBig
    (
        OrderID INT NOT NULL ,
        ProductID INT NOT NULL ,
        UnitPrice MONEY NOT NULL ,
        Quantity SMALLINT NOT NULL ,
        Discount REAL NOT NULL INDEX IX_OrderID NONCLUSTERED HASH ( OrderID )
                                   ) ,
        INDEX IX_ProductID NONCLUSTERED ( ProductID ) ,
        CONSTRAINT PK_Order_Details
            PRIMARY KEY NONCLUSTERED
                (
                    OrderID ,
                    ProductID
                ) ,
        INDEX clcsi_OrderDetailsBig CLUSTERED COLUMNSTORE
            )
    )
WITH ( MEMORY_OPTIMIZED = ON, DURABILITY = SCHEMA_AND_DATA );
GO
SELECT OBJECT_NAME(c.object_id) AS table_name ,
       a.xtp_object_id ,
       a.type_desc ,
       minor_id ,
       memory_consumer_id AS consumer_id ,
       memory_consumer_type_desc AS consumer_type_desc ,
       memory_consumer_desc AS consumer_desc ,
       ) AS allocated_MB ,
       ) AS used_MB
FROM   sys.memory_optimized_tables_internal_attributes a
       JOIN sys.dm_db_xtp_memory_consumers c ON a.object_id = c.object_id
                                                AND a.xtp_object_id = c.xtp_object_id
       LEFT JOIN sys.indexes i ON c.object_id = i.object_id

AND c.index_id = i.index_id;

返回的结果:

个内部表,xtp_object_id都不相同。每个内部表为了访问方便至少有一个索引用于数据访问。四个内部表:ROW_GROUP_INFO_TABLE(+hash索引),SEGMENTS_TABLE(+2个hash索引),DICTIONARIES_TABLE(+hash 索引),DELETED_ROW_TABLE(+hash索引)。(这些内部表的细节白皮书没有介绍)

除了看内存消费者之外,另外一个要检查的DMV是sys.dm_db_column_store_row_group_ physical_stats,这个视图不单单是显示了每个COMPRESSED并且OPEN的rowgroup的行数。你可以用一下脚本查看:

BEGIN TRAN;
;
)
    BEGIN
        INSERT INTO dbo.OrderDetailsBig
        , 0.5 );
        ;
        )
            BEGIN
                COMMIT TRAN;
                BEGIN TRAN;
            END;
    END;
COMMIT TRAN;
SELECT   row_group_id ,
         state_desc ,
         total_rows ,
         trim_reason_desc
FROM     sys.dm_db_column_store_row_group_physical_stats
WHERE    object_id = OBJECT_ID('dbo.OrderDetailsBig')
ORDER BY row_group_id;
GO

那么就显示NO_TRIM。因为OPEN的rowgroup是不压缩的,因此为null,若为STATS_MISMATCH表示行太少,若为SPILLOVER表示有移除导致。

SQL Server In-Memory OLTP Internals for SQL Server 2016的更多相关文章

  1. SQL Server 内存中OLTP内部机制概述(一)

    ----------------------------我是分割线------------------------------- 本文翻译自微软白皮书<SQL Server In-Memory ...

  2. SQL Server 内存中OLTP内部机制概述(四)

    ----------------------------我是分割线------------------------------- 本文翻译自微软白皮书<SQL Server In-Memory ...

  3. SQL Server 内存中OLTP内部机制概述(三)

    ----------------------------我是分割线------------------------------- 本文翻译自微软白皮书<SQL Server In-Memory ...

  4. SQL Server 内存中OLTP内部机制概述(二)

    ----------------------------我是分割线------------------------------- 本文翻译自微软白皮书<SQL Server In-Memory ...

  5. Sql Server 优化 SQL 查询:如何写出高性能SQL语句

    1. 首先要搞明白什么叫执行计划? 执行计划是数据库根据SQL语句和相关表的统计信息作出的一个查询方案,这个方案是由查询优化器自动分析产生的,比如一条SQL语句如果用来从一个 10万条记录的表中查1条 ...

  6. SQL Server定时自动抓取耗时SQL并归档数据发邮件脚本分享

    SQL Server定时自动抓取耗时SQL并归档数据发邮件脚本分享 第一步建库和建表 USE [master] GO CREATE DATABASE [MonitorElapsedHighSQL] G ...

  7. [转]SQL SERVER – Importance of Database Schemas in SQL Server

    原文地址http://blog.sqlauthority.com/2009/09/07/sql-server-importance-of-database-schemas-in-sql-server/ ...

  8. 安装 SQL Server 2008 时提示需要删除 SQL Server 2005 Express 工具

    已安装 SQL Server 2005,安装 SQL Server 2008 时提示需要删除 SQL Server 2005 Express 工具 错误提示:已安装 SQL Server 2005 E ...

  9. SQL Server代理(8/12):使用SQL Server代理外部程序

    SQL Server代理是所有实时数据库的核心.代理有很多不明显的用法,因此系统的知识,对于开发人员还是DBA都是有用的.这系列文章会通俗介绍它的很多用法. 在这个系列的上篇文章里,你学习如何使用SQ ...

随机推荐

  1. PTA 5-3 解题报告

    GitHub 问题描述 解题思路 代码 问题描述 5-3 计算平均值 (50分) 现在为若干组整数分别计算平均值. 已知这些整数的绝对值都小于100,每组整数的数量不少于1个,不大于20个. 输入格式 ...

  2. It is not safe to rely on the system's timezone settings错误

    在写php程序中有时会出现这样的警告: PHP Warning: date(): It is not safe to rely on the system's timezone settings. Y ...

  3. mysql找安装路经,更改密码

    1:如果安装了mysql但是启动不了,可以到C:/Windows/System32的cmd.exe,用管理员身份打开,然后输入net strat mysql即可 2:忘记安装路经       sele ...

  4. Java 多线程 重入锁

    作为关键字synchronized的替代品(或者说是增强版),重入锁是synchronized的功能扩展.在JDK 1.5的早期版本中,重入锁的性能远远好于synchronized,但从JDK 1.6 ...

  5. 使用8.0版本jdbc驱动连接数据库操作

    转自:https://blog.csdn.net/qq_41734885/article/details/80562815 首先,我居然不能用navicat客户端连接上mysql8.0数据库报1251 ...

  6. python对象转化为json串、json串转化为python串

    1.1. JSON简介: JavaScript Object Notation(JavaScript对象表示法) JSON是存储和交换文本信息的语法.类似XML JSON比XML更小.更快.更易解析 ...

  7. JS的document.links函数使用示例

    ? <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title&g ...

  8. hdu3466 Proud Merchants(01背包)

    https://vjudge.net/problem/HDU-3466 一开始想到了是个排序后的背包,但是排序的策略一直没对. 两个物品1和2,当p1+q2>p2+q1 => q1-p1& ...

  9. jQuery CVE-2019-11358原型污染漏洞分析和修复建议

    一.安全通告 jQuery官方于日前发布安全预警通告,通报了漏洞编号为 CVE-2019-11358的原型污染漏洞.由攻击者控制的属性可被注入对象,之后或经由触发 JavaScript 异常引发拒绝服 ...

  10. Docker国内镜像source

    现在使用docker的镜像大多基于几种基本Linux系统.虽然我不需要在容器李安装很多东西,但经常需要一些必要的工具,而基础镜像里并不包含,比如vim, ifconfig, curl等.考虑下载速度, ...