1. 程式人生 > >試試SQLServer 2014的記憶體優化表(轉載)

試試SQLServer 2014的記憶體優化表(轉載)

SQL Server2014儲存引擎:行儲存引擎,列儲存引擎,記憶體引擎

SQL Server 2014中的記憶體引擎(代號為Hekaton)將OLTP提升到了新的高度。

現在,儲存引擎已整合進當前的資料庫管理系統,而使用先進記憶體技術來支援大規模OLTP工作負載。

就算如此,要利用此新功能,資料庫必須包含“記憶體優化”檔案組和表

即所配置的檔案組和表使用Hekaton技術。

幸運的是,SQL Server 2014使這一過程變得非常簡單直接。

要說明其工作原理,我們來建立一個名為TestHekaton的資料庫,然後新增一個記憶體優化檔案組到此資料庫

 

測試環境:Microsoft Azure 大陸版 虛擬機器

4核 ,7G記憶體,Windows2012R2

SQLSERVER2014企業版

 

 

第一個實驗:記憶體表的簡單使用


 

步驟1:建立資料庫和MEMORY_OPTIMIZED_DATA檔案組

USE master;

GO

CREATE DATABASE TestHekaton;

GO

ALTER DATABASE TestHekaton

ADD FILEGROUP HekatonFG CONTAINS MEMORY_OPTIMIZED_DATA;

GO

注意ALTER DATABASE語句中的ADD FILEGROUP 語句包含檔案組的名稱(HekatonFG

)和關鍵字CONTAINS MEMORY_OPTIMIZED_DATA

它會指導SQL Server去建立支援記憶體OLTP引擎所必需的檔案組型別。

注意:每個資料庫只能有一個MEMORY_OPTIMIZED_DATA檔案組!!

要確認此檔案組已經建立,可以訪問SSMS中資料庫屬性的Filegroups 介面,如下圖所示。

 

步驟2:

新增一個存放資料檔案的資料夾到檔案組,可以通過ALTER DATABASE語句來實現。

新增一個存放記憶體優化表資料的資料夾到HekatonFG檔案組:

--執行下面語句之後會在C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\DATA路徑下建立一個資料夾
--資料夾名為HekatonFile --請不要預先建立好這個資料夾 ALTER DATABASE TestHekaton ADD FILE ( NAME = 'HekatonFile', FILENAME ='C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\DATA\HekatonFile' ) TO FILEGROUP [HekatonFG]; GO

注意:在ADD FILE 語句中,我們只為檔案路徑提供了一個友好的名稱。

並且,在TO FILEGROUP 語句中,指定剛才新建的檔案組名字

然後可以去往資料庫屬性的 Files 介面來檢視剛剛新增的檔案,如圖所示。

比如是這樣

ALTER DATABASE [test99]
ADD FILE
(
   NAME = 'HekatonFile',
   FILENAME ='D:\DataBase\xtp\'
)
TO FILEGROUP [HekatonFG];
GO

 

步驟3:

在為資料庫設定了必需的檔案組和檔案之後,就可以建立自己的記憶體優化表了。

當在定義表的時候,會指定其“永續性”。

一個記憶體優化表可以是持久的非持久的

(1)對於一個持久表是將資料儲存在記憶體中,而且也儲存在記憶體優化檔案組中。

(2)對於一個非持久表,資料是僅儲存在記憶體中的,所以,如果系統崩潰或重啟,資料就會丟失。

 

在SQL Server 2014中預設用的是持久表,接下來我們來深入瞭解一下。

當定義一個持久記憶體優化表的時候,你還必須定義一個基於非聚集雜湊索引的主鍵。

在一個雜湊索引中,資料是通過一個記憶體散列表進行訪問的,而非固定大小頁。

雜湊索引是在記憶體優化表中唯一支援的索引型別。

除了在表定義中定義主鍵外,還必須將表配置為記憶體優化的,如下CREATE TABLE 語句所示:

USE TestHekaton;
GO

CREATE TABLE Reseller
    (
      [ResellerID] INT NOT NULL
                       PRIMARY KEY NONCLUSTERED HASH WITH (BUCKET_COUNT = 1024),
      [ResellerName] NVARCHAR(50) NOT NULL ,
      [ResellerType] NVARCHAR(20) NOT NULL
    )
WITH (MEMORY_OPTIMIZED = ON, DURABILITY = SCHEMA_AND_DATA);

INSERT  INTO Reseller
VALUES  ( 1, 'A Bike Store', 'Value Added Reseller' );

 

ResellerID 欄位包含了定義為非聚集雜湊的主鍵。

注意,必須包含一個WITH 語句來指定BUCKET_COUNT 的設定,它表明了在雜湊索引中應該建立的bucket數量。

(每個bucket是一個槽,可以用來存放一組鍵值對。)

微軟建議bucket的數量應是一到兩倍於你所期望的表所要包含的唯一索引鍵的數量。

由於每個資料庫只能有一個MEMORY_OPTIMIZED_DATA檔案組,所以建立表的時候就不需要指定表建立在哪個MEMORY_OPTIMIZED_DATA檔案組了

 

此表定義以第二個WITH 語句結束。

這裡你指定MEMORY_OPTIMIZED 選項為ON 以及DURABILITY 選項為SCHEMA_AND_DATA,此選項是針對持久表的。

接著在表中插入一條記錄,這樣就可以進行測試了。

資料已經插入到表中

 

這就是建立一個記憶體優化表的全部步驟。

但是,要記住,SQL Server 2014對這些表有著很多限制。例如,它們不支援外來鍵約束檢查(感覺類似於MySQL的memory儲存引擎),

它們也不支援IDENTITY 欄位或DML觸發器。最為重要的是,記憶體耗盡會導致資料寫入失敗。

 

步驟4:

另一方面,記憶體優化表支援本地編譯儲存過程,只要那些儲存過程只引用記憶體優化表。

在這種情況下,儲存過程可以轉化為原生代碼native code,這樣會執行更快且要比典型儲存過程需要更少的記憶體。

除了只引用記憶體優化表,一個本地編譯儲存過程必須是模式繫結的並執行在一個特定執行內容內。

另外,每個本地編譯儲存過程必須完全由一個原子塊組成。

 

下面的CREATE PROCEDURE 語句定義了一個本地編譯儲存過程,它從前面所建立的Reseller表中檢索資料

CREATE PROCEDURE GetResellerType ( @id INT )
    WITH NATIVE_COMPILATION,
         SCHEMABINDING,
         EXECUTE AS OWNER
AS
    BEGIN
  ATOMIC WITH(TRANSACTION ISOLATION LEVEL = SNAPSHOT, LANGUAGE = 'us_english')
        SELECT  ResellerName ,
                ResellerType
        FROM    dbo.Reseller
        WHERE   ResellerID = @id
    END;
GO

 

在定義了引數之後,包含一個WITH 語句來指定NATIVE_COMPILATION 選項。

注意:此語句還包含SCHEMABINDING 選項和EXECUTE AS 選項,以及指定了OWNER 作為執行環境。

而WITH 語句負責實現本地編譯儲存過程的三大需求。

要解決原子塊需求,可以在BEGIN 關鍵字後指定ATOMIC ,之後是另一個包含有事務隔離級別和語言的WITH 語句。

對於訪問記憶體優化表的事務,可以使用SNAPSHOT,REPEATABLEREAD 或SERIALIZABLE 作為隔離級別。

而且,對於此語言必須使用一個可用的語言或語言別名。

這是在定義儲存過程時所需要包含的全部內容。一旦建立,就可以通過執行EXECUTE 語句來對其加以測試,如下例中所示:

EXEC GetResellerType 1;

 

此語句會返回經銷商的姓名和型別,在本例中分別是ABike Store和Value Added Reseller。

 

記憶體優化表不使用 TempDB 來儲存行版本,所以使用記憶體優化表不用擔心tempdb資料庫會暴增。

 

即使沒有開啟snapshot隔離級別,記憶體優化表預設會開啟snapshot隔離級別,對記憶體優化表的訪問使用的都是snapshot隔離級別

事務不會對記憶體優化表使用鎖和閂鎖,但是又可以預設使用snapshot隔離級別保證資料一致性,這是記憶體表的強大之處

use [test99]

/****** Script for SelectTopNRows command from SSMS  ******/
SELECT TOP 1000 [ResellerID]
      ,[ResellerName]
      ,[ResellerType]
  FROM [test99].[dbo].[Reseller] WITH (SNAPSHOT) where [ResellerID]>0 and [ResellerID] <60

 

 

第二個實驗:記憶體表的資料查詢速度比較


 

聚集索引表和記憶體優化表的比較

建表語句

USE TestHekaton;
GO

--記憶體優化表
CREATE TABLE testmemory1
    (
      [ID] FLOAT NOT NULL
                       PRIMARY KEY NONCLUSTERED HASH WITH (BUCKET_COUNT = 1024),
      [Name] NVARCHAR(50) NOT NULL 
    )
WITH (MEMORY_OPTIMIZED = ON, DURABILITY = SCHEMA_AND_DATA);

 

USE TestHekaton;
GO

--聚集索引表
CREATE TABLE testmemory2
    (
      [ID] FLOAT NOT NULL PRIMARY KEY,
      [Name] NVARCHAR(50) NOT NULL 
    )

 

---------------------------------------------------------------

插入效能比較

記憶體優化表

SET STATISTICS IO ON 
SET STATISTICS TIME ON
INSERT into testmemory1([id],[name])  SELECT [id] ,[name] from sysobjects
SET STATISTICS IO OFF
SET STATISTICS TIME OFF

 

Table 'sysschobjs'. Scan count 1, logical reads 33, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 20 ms.
(90 row(s) affected)
 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.
 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.

 

聚集索引表

SET STATISTICS IO ON 
SET STATISTICS TIME ON
INSERT into testmemory2([id],[name])  SELECT [id] ,[name] from sysobjects
SET STATISTICS IO OFF
SET STATISTICS TIME OFF

 

Table 'testmemory2'. Scan count 0, logical reads 183, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'sysschobjs'. Scan count 1, logical reads 33, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 10 ms.
(90 row(s) affected)
 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.

 

 

-------------------------------------------------------------------------------

查詢效能比較

記憶體優化表

SET STATISTICS IO ON 
SET STATISTICS TIME ON
SELECT * FROM  testmemory1  ORDER BY [ID] DESC
SET STATISTICS IO ON
SET STATISTICS TIME ON

 

SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 1 ms.
 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.
 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.
(90 row(s) affected)
 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.
 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.

 

聚集索引表

SET STATISTICS IO ON 
SET STATISTICS TIME ON
SELECT * FROM  testmemory2  ORDER BY [ID] DESC
SET STATISTICS IO ON
SET STATISTICS TIME ON

 

(91 row(s) affected)
Table 'testmemory2'. Scan count 1, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.
 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.

 

可以看到記憶體優化表讀寫資料(insert 、select)的時候都看不到IO讀寫

 

 

補充測試:


 

我們先刪除剛才插入的資料,記憶體優化表是不支援truncate table的,只能用delete from 表

只能夠delete

 

-------------------------------------------------------------------------------------------------

插入測試

記憶體優化表

聚集索引表

 

-------------------------------------------------------------------------------------------------

查詢測試

記憶體優化表

聚集索引表

 

-------------------------------------------------------------------------------------------------

我們看一下事務日誌

CHECKPOINT
GO

SELECT Context ,
Operation,
AllocUnitName
FROM sys.fn_dblog(NULL, NULL)

 

Context Operation AllocUnitName
LCX_NULL LOP_HK NULL
LCX_NULL LOP_HK_CHAINED NULL
LCX_NULL LOP_HK NULL
LCX_NULL LOP_HK_CHAINED NULL
LCX_NULL LOP_HK_CHECKPOINT NULL
LCX_NULL LOP_HK NULL
LCX_NULL LOP_BEGIN_XACT NULL
LCX_NULL LOP_FS_DOWNLEVEL_OP NULL
LCX_NULL LOP_BEGIN_XACT NULL
LCX_CLUSTERED LOP_INSERT_ROWS sys.filestream_tombstone_2073058421.FSTSClusIdx
LCX_INDEX_LEAF LOP_INSERT_ROWS sys.filestream_tombstone_2073058421.FSTSNCIdx
LCX_NULL LOP_COMMIT_XACT NULL
LCX_MARK_AS_GHOST LOP_DELETE_ROWS sys.filestream_tombstone_2073058421.FSTSClusIdx
LCX_MARK_AS_GHOST LOP_DELETE_ROWS sys.filestream_tombstone_2073058421.FSTSNCIdx
LCX_NULL LOP_HK NULL
LCX_NULL LOP_FS_DOWNLEVEL_OP NULL
LCX_HEAP LOP_INSERT_ROWS sys.xtp_storage
LCX_INDEX_LEAF LOP_INSERT_ROWS sys.xtp_storage.UQ__xtp_stor__3213E83EA8737D06
LCX_CLUSTERED LOP_EXPUNGE_ROWS sys.filestream_tombstone_2073058421.FSTSClusIdx
LCX_CLUSTERED LOP_EXPUNGE_ROWS sys.filestream_tombstone_2073058421.FSTSClusIdx
LCX_PFS LOP_SET_BITS sys.filestream_tombstone_2073058421.FSTSClusIdx
LCX_INDEX_LEAF LOP_EXPUNGE_ROWS sys.filestream_tombstone_2073058421.FSTSNCIdx
LCX_INDEX_LEAF LOP_EXPUNGE_ROWS sys.filestream_tombstone_2073058421.FSTSNCIdx
LCX_NULL LOP_COMMIT_XACT NULL
LCX_NULL LOP_BEGIN_XACT NULL
LCX_NULL LOP_FS_DOWNLEVEL_OP NULL
LCX_NULL LOP_BEGIN_XACT NULL
LCX_CLUSTERED LOP_INSERT_ROWS sys.filestream_tombstone_2073058421.FSTSClusIdx
LCX_INDEX_LEAF LOP_INSERT_ROWS sys.filestream_tombstone_2073058421.FSTSNCIdx
LCX_NULL LOP_COMMIT_XACT NULL
LCX_MARK_AS_GHOST LOP_DELETE_ROWS sys.filestream_tombstone_2073058421.FSTSClusIdx
LCX_PFS LOP_SET_BITS sys.filestream_tombstone_2073058421.FSTSClusIdx
LCX_MARK_AS_GHOST LOP_DELETE_ROWS sys.filestream_tombstone_2073058421.FSTSNCIdx
LCX_NULL LOP_FS_DOWNLEVEL_OP NULL
LCX_HEAP LOP_INSERT_ROWS sys.xtp_storage
LCX_INDEX_LEAF LOP_INSERT_ROWS sys.xtp_storage.UQ__xtp_stor__3213E83EA8737D06
LCX_NULL LOP_COMMIT_XACT NULL
LCX_NULL LOP_HK NULL
LCX_CLUSTERED LOP_EXPUNGE_ROWS sys.filestream_tombstone_2073058421.FSTSClusIdx
LCX_INDEX_LEAF LOP_EXPUNGE_ROWS sys.filestream_tombstone_2073058421.FSTSNCIdx
LCX_PFS LOP_SET_BITS sys.filestream_tombstone_2073058421.FSTSClusIdx
LCX_PFS LOP_SET_BITS sys.filestream_tombstone_2073058421.FSTSNCIdx
LCX_CLUSTERED LOP_COUNT_DELTA sys.sysallocunits.clust
LCX_CLUSTERED LOP_COUNT_DELTA sys.sysrowsets.clust
LCX_CLUSTERED LOP_COUNT_DELTA sys.sysrscols.clst
LCX_CLUSTERED LOP_COUNT_DELTA sys.sysrscols.clst
LCX_CLUSTERED LOP_COUNT_DELTA sys.sysrscols.clst
LCX_CLUSTERED LOP_COUNT_DELTA sys.sysrscols.clst
LCX_CLUSTERED LOP_COUNT_DELTA sys.sysrscols.clst
LCX_CLUSTERED LOP_COUNT_DELTA sys.sysrscols.clst
LCX_CLUSTERED LOP_COUNT_DELTA sys.sysrscols.clst
LCX_CLUSTERED LOP_COUNT_DELTA sys.sysrscols.clst
LCX_CLUSTERED LOP_COUNT_DELTA sys.sysrscols.clst
LCX_CLUSTERED LOP_COUNT_DELTA sys.sysrscols.clst
LCX_CLUSTERED LOP_COUNT_DELTA sys.sysallocunits.clust
LCX_CLUSTERED LOP_COUNT_DELTA sys.sysrowsets.clust
LCX_CLUSTERED LOP_COUNT_DELTA sys.sysallocunits.clust
LCX_CLUSTERED LOP_COUNT_DELTA sys.sysrowsets.clust
LCX_CLUSTERED LOP_COUNT_DELTA sys.sysrscols.clst
LCX_CLUSTERED LOP_COUNT_DELTA sys.sysrscols.clst
LCX_CLUSTERED LOP_COUNT_DELTA sys.sysrscols.clst
LCX_CLUSTERED LOP_COUNT_DELTA sys.sysallocunits.clust
LCX_CLUSTERED LOP_COUNT_DELTA sys.sysrowsets.clust
LCX_NULL LOP_BEGIN_CKPT NULL
LCX_FILE_HEADER LOP_MODIFY_STREAMFILE_HDR NULL
LCX_BOOT_PAGE_CKPT LOP_XACT_CKPT NULL
LCX_NULL LOP_END_CKPT NULL
LCX_NULL LOP_HK NULL
LCX_NULL LOP_HK NULL
LCX_NULL LOP_HK NULL
LCX_NULL LOP_HK_CHAINED NULL
LCX_NULL LOP_HK NULL
LCX_NULL LOP_HK NULL
LCX_NULL LOP_BEGIN_XACT NULL
LCX_NULL LOP_FS_DOWNLEVEL_OP NULL
LCX_NULL LOP_BEGIN_XACT NULL
LCX_CLUSTERED LOP_INSERT_ROWS sys.filestream_tombstone_2073058421.FSTSClusIdx
LCX_INDEX_LEAF LOP_INSERT_ROWS sys.filestream_tombstone_2073058421.FSTSNCIdx
LCX_NULL LOP_COMMIT_XACT NULL
LCX_MARK_AS_GHOST LOP_DELETE_ROWS sys.filestream_tombstone_2073058421.FSTSClusIdx
LCX_PFS LOP_SET_BITS sys.filestream_tombstone_2073058421.FSTSClusIdx
LCX_MARK_AS_GHOST LOP_DELETE_ROWS sys.filestream_tombstone_2073058421.FSTSNCIdx
LCX_PFS LOP_SET_BITS sys.filestream_tombstone_2073058421.FSTSNCIdx
LCX_NULL LOP_HK_CHAINED NULL
LCX_NULL LOP_HK_CHAINED NULL
LCX_NULL LOP_HK_CHECKPOINT NULL
LCX_NULL LOP_FS_DOWNLEVEL_OP NULL
LCX_HEAP LOP_INSERT_ROWS sys.xtp_storage
LCX_INDEX_LEAF LOP_INSERT_ROWS sys.xtp_storage.UQ__xtp_stor__3213E83EA8737D06
LCX_NULL LOP_COMMIT_XACT NULL
LCX_NULL LOP_BEGIN_XACT NULL
LCX_NULL LOP_FS_DOWNLEVEL_OP NULL
LCX_NULL LOP_BEGIN_XACT NULL
LCX_CLUSTERED LOP_INSERT_ROWS sys.filestream_tombstone_2073058421.FSTSClusIdx
LCX_INDEX_LEAF LOP_INSERT_ROWS sys.filestream_tombstone_2073058421.FSTSNCIdx
LCX_NULL LOP_COMMIT_XACT NULL
LCX_MARK_AS_GHOST LOP_DELETE_ROWS sys.filestream_tombstone_2073058421.FSTSClusIdx
LCX_MARK_AS_GHOST LOP_DELETE_ROWS sys.filestream_tombstone_2073058421.FSTSNCIdx
LCX_NULL LOP_FS_DOWNLEVEL_OP NULL
LCX_HEAP LOP_INSERT_ROWS sys.xtp_storage
LCX_INDEX_LEAF LOP_INSERT_ROWS sys.xtp_storage.UQ__xtp_stor__3213E83EA8737D06
LCX_NULL LOP_COMMIT_XACT NULL
LCX_NULL LOP_HK NULL
LCX_CLUSTERED LOP_EXPUNGE_ROWS sys.filestream_tombstone_2073058421.FSTSClusIdx
LCX_CLUSTERED LOP_EXPUNGE_ROWS sys.filestream_tombstone_2073058421.FSTSClusIdx
LCX_INDEX_LEAF LOP_EXPUNGE_ROWS sys.filestream_tombstone_2073058421.FSTSNCIdx
LCX_INDEX_LEAF LOP_EXPUNGE_ROWS sys.filestream_tombstone_2073058421.FSTSNCIdx
LCX_PFS LOP_SET_BITS sys.filestream_tombstone_2073058421.FSTSClusIdx
LCX_PFS LOP_SET_BITS sys.filestream_tombstone_2073058421.FSTSNCIdx
LCX_PFS LOP_MODIFY_HEADER Unknown Alloc Unit

 

 

總結


 

記憶體優化表也會寫事務日誌的,在讀寫操作的時候發現記憶體優化表沒有I/O次數,應該是資料都已經在記憶體裡了

 

記憶體優化表的主要技術限制
1. 排序規則
記憶體優化表的排序規則可以從資料庫的排序規則繼承下來,也可使用 COLLATE 關鍵字顯式指定。 如果資料庫包含記憶體優化表或本機編譯儲存過程,則無法更改資料庫排序規則。
  排序規則必須是1252內碼表,例如 SQL_Latin1_General_CP1_CI_AS。否則報錯。
訊息 12329,級別 16,狀態 103,第 1 行
記憶體優化表 不支援使用的排序規則所具有的內碼表並非 1252 的資料型別 char(n) 和 varchar(n)。
  作為一種變通的方案,可以使用資料型別 nchar(n) 和 nvarchar(n) 。

2. 資料行的寬度
每一行資料不能超過1個頁(8KB)。否則報錯。
訊息 41307,級別 16,狀態 1,第 1 行
已超過記憶體優化的表的 8060 位元組行大小限制。請簡化表定義。

3. 索引
非聚集雜湊索引是記憶體優化表唯一支援的索引型別。在一個雜湊索引中,資料是通過一個記憶體散列表進行訪問的,而非固定大小頁。

4. 記憶體優化表事務隔離級別
訪問記憶體優化表的事務支援的隔離級別:SNAPSHOT,REPEATABLE READ,SERIALIZABLE,READ COMMITTED 。
記憶體優化表不使用鎖。只能使用更高的隔離級別(如 REPEATABLE READ 和 SERIALIZABLE)。
不支援鎖定提示。改為通過事務隔離級別更改。
(支援 NOLOCK 是因為 SQL Server 不對記憶體優化表使用鎖。請注意,與基於磁碟的表不同,NOLOCK 對於記憶體優化表並不表示跟READ UNCOMMITTED 行為相同。)

 

事務

跨容器事務

術語“跨容器”源於這樣的事實:事務跨兩個事務管理容器執行,一個用於基於磁碟的表,另一個用於記憶體優化表。
一個事務需要訪問磁碟表和記憶體表就叫跨容器事務

在單個跨容器事務中,可以使用不同的隔離級別來訪問基於磁碟的表和記憶體優化表。
這種差異通過顯式表提示(如 WITH (SERIALIZABLE))或資料庫選項 MEMORY_OPTIMIZED_ELEVATE_TO_SNAPSHOT(如果事務隔離級別配置為 READ COMMITTED 或 READ UNCOMMITTED,此選項會將記憶體優化表的隔離級別隱式提升為 SNAPSHOT)來體現。


如果使用跨容器事務需要設定
針對整個庫
ALTER DATABASE CURRENT SET MEMORY_OPTIMIZED_ELEVATE_TO_SNAPSHOT=ON

針對單條語句
WITH (SERIALIZABLE)
WITH (SNAPSHOT)

--(1)不開啟MEMORY_OPTIMIZED_ELEVATE_TO_SNAPSHOT 要顯式使用with(snapshot)
ALTER DATABASE [test] SET MEMORY_OPTIMIZED_ELEVATE_TO_SNAPSHOT=off

BEGIN TRANSACTION;  

   
SELECT * FROM  [dbo].[users] AS A INNER JOIN  [dbo].[Reseller]   AS B with(snapshot)
ON A.ID=B.RESELLERID 
 

COMMIT TRANSACTION; 


--(2)開啟MEMORY_OPTIMIZED_ELEVATE_TO_SNAPSHOT 
ALTER DATABASE [test] SET MEMORY_OPTIMIZED_ELEVATE_TO_SNAPSHOT=on

BEGIN TRANSACTION;  

   
SELECT * FROM  [dbo].[users] AS A INNER JOIN  [dbo].[Reseller]   AS B 
ON A.ID=B.RESELLERID 
 

COMMIT TRANSACTION;

 

如果大家接觸過redis資料庫的話,上面的限制其實不難理解,走起君覺得記憶體優化表其實就是把redis資料庫嵌入到SQL Server裡面,並加入了一些關係型資料庫特性

 

更多詳細資料可以參考:

SQL Server 2014 新特性——記憶體資料庫

SQL Server 2014新特性:分割槽索引和記憶體優化表

MSDN:記憶體優化表

SQL Server 2014 記憶體優化表(1)實現記憶體優化表

SQLServer 2014 記憶體優化表

MSDN:記憶體優化表中的事務

 

 

原文連結