SQL Server 2014 新特性——內存數據庫


 

 

SQL Server 2014 新特性——內存數據庫

目錄

SQL Server 2014 新特性——內存數據庫... 1

簡介:... 1

設計目的和原因:... 1

專業名詞... 1

In-Memory OLTP不同之處... 2

內存優化表... 2

內存優化表的索引... 2

並發能力的提升... 3

和競爭對手相比幾點... 3

Getting Start. 3

內存數據庫的使用... 3

存儲... 5

TSQL支持... 7

 

 

簡介:

     內存數據庫(In-Memory OLTP),代號Hekaton

設計目的和原因:

         1.將請求的負荷放到內存中

         2.減少數據延遲

         3.來適應特殊的負荷類型

        

         如果數據都是在內存中,那么當前的數據庫優化器產生的執行計划是沒什么意義的,因為現在的優化器默認數據在磁盤中而不是在內存中,所以不從磁盤中讀取數據,優化器應該使用新的執行計划和新的開銷算法。

 

         In-Memory OLTP 減少了鎖等待問題,使用基於行版本來優化同步的控制,改善了寫入等待的延遲,寫入日志變少,寫入次數變少。

專業名詞

Memory-optimized tables索引優化表:引入了新的結構,被加入到in-memory oltp的新表

Disk-Based tables(磁盤表):基礎磁盤存放的表,就是我們一直使用的表。

Natively complied原生編譯存儲過程用於索引優化表的訪問也可以使用tsql訪問通過原生編譯存儲過程訪問速度會更快一點

嵌套事務:可以在優化表中使用,也可以在磁盤表中使用

interop:可以讓tsql訪問索引優化表

 

In-Memory OLTP不同之處


通過圖可以發現,原生編譯存儲過程只能使用在內存優化表上,而query interop用戶tsql訪問內存優化表的橋梁

內存優化表

         1.內存優化表和硬盤表不同,不需要把數據從硬盤上讀取放入cache中,

         2.checkpoint只是用戶恢復的目的

         3.和硬盤表一樣,使用事務日志,當服務重啟后,使用checkpoint的文件和日志,對內存優化表進行重建

         4.內存優化表可以通過選項來設置表的持久性:SCHEMA_ONLY只保存表的結構,不保存數據,當服務重啟后數據就會丟失

內存優化表的索引

         1.內存優化表中的索引不再以btree方式存儲,而是以hash 表的方式

         2.內存優化表必須有一個索引,並沒有堆表的概念

         3.索引,不會被保存在文件或者事務日志,並會根據內存優化表的修改自動維護,在所有重啟時,根據表的文件和日志重建索引

並發能力的提升

         1.以行版本的方式存儲表數據,修改數據時會請求鎖,但是在內存優化表中不會

         2.雖然沒有寫入鎖,但是還是有等待比如log write,比硬盤表高效,寫入的日志少,速度快

和競爭對手相比幾點

         1.內存表和硬盤表通過interop集成,有利於過渡

         2.原生編譯存儲過程,效率高

         3.hash索引,提高內存訪問效率

         4.沒有page,不會出現page latch的等待

         5.通過行版本實現,不需要locklatch

Getting Start

內存數據庫的使用

創建數據庫

CREATE DATABASE HKDB

ON

PRIMARY(NAME = [HKDB_data],

FILENAME = 'Q:\data\HKDB_data.mdf', size=500MB),

FILEGROUP [SampleDB_mod_fg] CONTAINS MEMORY_OPTIMIZED_DATA

(NAME = [HKDB_mod_dir],

FILENAME = 'R:\data\HKDB_mod_dir'),

(NAME = [HKDB_mod_dir],

FILENAME = 'S:\data\HKDB_mod_dir')

LOG ON (name = [SampleDB_log], Filename='L:\log\HKDB_log.ldf', size=500MB)

COLLATE Latin1_General_100_BIN2;

在創建庫時需要制定 MEMORY_OPTIMIZED_DATA文件組,用來保存checkpointdelta文件,

創建的數據庫只能使用BIN2排序規則,原生編譯存儲過程只能支持在這些規則上比較,排序,分組

添加MEMORY_OPTIMIZED_DATA到已有數據庫

ALTER DATABASE AdventureWorks2012 ADD FILEGROUP hk_mod CONTAINS MEMORY_OPTIMIZED_DATA;

GO

ALTER DATABASE AdventureWorks2012 ADD FILE (NAME='hk_mod', FILENAME='c:\data\hk_mod')

TO FILEGROUP hk_mod;

GO

創建表

CREATE TABLE T1 (

[Name] varchar(32) not null PRIMARY KEY NONCLUSTERED HASH WITH (BUCKET_COUNT = 1024),

[City] varchar(32) null,

[LastModified] datetime not null,

) WITH (MEMORY_OPTIMIZED = ON, DURABILITY = SCHEMA_AND_DATA);

 

         1.創建內存優化表是需要注明,MEMORY_OPTIMIZED=ON,並設置持久性

2.bit,tinyint,smallint,int,bigint,money,smallmoney,float,real,datetime,smalldatetime,datetime2,date,time,numeric,decimal,char,varchar,nchar,nvarchar,sysname,binary,varbinary,uniqueidentifier

BLOB的數據類型都是不被支持的

         3.2個持久性選項:1.SCHEMA_AND_DATA持久化數據和結構,2.SCHEMA_ONLY只持久化結構

         4.每個表至少有一個索引,會自動為主鍵約束創建索引,在創建索引是要指定hash索引的bucket_count

         5.創建表后,內存數據庫引擎會自動加載用於DML的原生編譯存儲過程,像加載ddl一樣

         6.SQL Server 自身不操作內存數據庫的數據,而是通過ddl來操作

         7.內存數據庫的限制:1.沒有觸發器,2.沒有外鍵和check3.沒有identity4.沒有主鍵以外的唯一索引5.最大8個索引,包括主鍵索引,9.不能通過alter table修改表結構,索引沒有DDL,索引是和表一體的,作為表的一部分創建

 

存儲

內存優化表使用內存字節地址,來代替磁盤區塊地址,不想堆表,內存優化表的行並不是存放在一起的,而是通過一個標記,來指明是同一個索引

                   結構圖

每行分為,行頭和payload

         行頭有begints(行插入時間),endts(行刪除時間),stmtid(保存事務中的語句id),idxlinkcount(索引引用計數器,若為0,會被指向到垃圾回收器),最后面8個字節*索引個數,說明內存表的索引。

         payload是數據區,包含key和所有其他列,所以hash索引都是覆蓋索引。

Hash索引

         hash索引是一組指針,每個組中的單元叫做hash bucketindex key通過hash計算把所有相同的hash值用同一個指針。

         當索引被創建的時候,必須制定bucket大小,大小必須大於表中會產生的bucket大小,每個bucket都是使用內存的,並且是2的整數次冪,若設置的太多不但不會提升性能,然后會在掃描的時候降低性能。

數據操作

通過維護一個內部事務id(時間戳)來確定一個事務可見的行版本。

有三個時間需要留意:

         1.Commit/End Time 每個事務數據被修改的時間都稱為 Commit Time或者End Time

         2.Valid Time 可用時間,由3部分組成,BeginTx(行版本插入時間),Endtx(行版本刪除時間),在之間的就是可用時間

         3.Logical Read Time 讀時間可以是事務開始到現在的任何時間,只要行版本的可用時間可以覆蓋讀時間,那么行版本就是可讀的,對於讀提交之外的隔離級別讀取時間是事務的開始時間,對於讀提交讀取時間是語句的執行時間。

 

隔離級別

內存數據庫支持一下幾種隔離級別:

         1.快照

         2.可持續讀

         3.串行

         只有在自動提交事務里面才能支持讀提交隔離級別,顯式事務或者隱式提交事務都不支持讀提交隔離級別

         當不訪問硬盤表的自動提交事務可以支持讀提交快照,當使用TSQL啟用快照隔離級別,不能訪問內存優化表,當使用TSQL使用串行隔離級別,要使用快照隔離級別訪問訪問內存優化表。

DML

         刪除:刪除操作只會在endtx上寫入一個時間戳,表示數據是否活躍,任何活動中的事務要訪問這條數據,在時間戳范圍內,都要看是否在該記錄還是活躍。

         插入/修改:修改操作時先插入后刪除,任何寫沖突的事務都會直接報錯,修改完成后,要開始檢查隔離級別,如果隔離級別不對,那么就回滾。任何修改都會被記入write set中,有個指針執行相關的行。

         讀取:以讀取時間為時間點,讀取可以覆蓋讀取時間的行

         驗證:因為內存數據庫沒有鎖,所以要使用驗證來保證一致性:

                   1.快照隔離級別,commit出錯,由2個以上插入同一個主鍵

                   2.可持續讀,讀取的行,在提交前被另外一個事務修改

                   3.串行,讀取可用行出錯,或者出現幻影,無法保證串行

TSQL支持

解釋型TSQL

         通過interop可以使用tsql訪問內存優化表,性能比原生編譯存儲過程差,但是方便,易兼容。

         不支持truncate,merge,動態、鍵值游標,交叉數據庫查詢,交叉數據庫事務,連接服務器,鎖提示,READUNCOMMITTED,READCOMMITTED,READCOMMITTEDLOCK這幾個隔離界別的提示,內存表類型和變量不支持。

原生編譯存儲過程

         優點:可以執行的更快,有不少的限制,如數據類型和排序規則,不能用於訪問硬盤表

         缺點:兼容性差

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM