適用於:SQL Server
Azure SQL 資料庫
Azure SQL 受控執行個體
記憶體內線上交易處理(OLTP)採用原生編譯技術,提供比傳統直譯式 Transact-SQL 更快的資料存取與更有效率的查詢執行。 原生編譯資料表與儲存程序會產生 動態連結函式庫 (DLL)。
SQL Server Database Engine 能原生編譯記憶體最佳化資料表、存取記憶體最佳化資料表的儲存程序,以及記憶體最佳化資料表類型。 如需詳細資訊,請參閱 使用記憶體最佳化加快暫存資料表與資料表變數的速度。
記憶體內部 OLTP 會在建立記憶體最佳化資料表時加以編譯,並在載入預存程序時,將其原生編譯為原生 DLL。 此外,DLL 在資料庫或伺服器重啟後會被重新編譯。 資料庫儲存重建 DLL 所需的資訊,並以元資料形式呈現。 DLL 不屬於資料庫,但它們與資料庫有關聯。 例如,DLL 不包含在資料庫備份中。
注意
記憶體優化的表格會在伺服器重新啟動後重新編譯。 為了加快資料庫復原,伺服器不會在重新啟動時重新編譯原生編譯的儲存程序。 而是在首次執行時編譯這些資料。 由於這種延遲編譯,原生編譯的儲存程序僅在首次執行後呼叫 sys.dm_os_loaded_modules 時才會出現。
記憶體內 OLTP DLL 的維護
下列查詢顯示目前載入伺服器記憶體中的所有資料表和預存程序 DLL:
SELECT mod1.name,
mod1.description
FROM sys.dm_os_loaded_modules AS mod1
WHERE mod1.description = 'XTP Native DLL';
資料庫管理員不需要維護由原生編譯產生的檔案。 資料庫引擎 會自動移除不再需要的已產生檔案。 例如,當資料表和儲存程序被刪除,或資料庫被丟棄時,產生的檔案也會被刪除。
注意
如果編譯失敗或中斷,部分產生的檔案不會被移除。 刻意留下這些檔案是為了提供支援,而這些檔案會在資料庫卸除時移除。
資料庫引擎 會編譯所有資料庫復原所需的資料表的 DLL。 如果資料表在資料庫重啟前被丟棄,該資料表的殘留物可能會存在於檢查點檔案或交易日誌中。 因此,資料表的 DLL 可能會在資料庫啟動時被重新編譯。 若此程序發生於資料庫重啟後,正常清理程序會卸載 DLL 並移除檔案。
資料表的原生編譯
當你使用 該 CREATE TABLE 語句建立記憶體優化資料表時,資料表資訊會寫入資料庫的元資料,而資料表和索引結構則是在記憶體中建立的。 接著,該資料表會被編譯成 DLL。
以下範例腳本建立資料庫與記憶體優化資料表。 確保你設定 FILENAME 路徑到 DATA 子目錄所在的位置。
USE master;
GO
CREATE DATABASE DbMemOpt3;
GO
ALTER DATABASE DbMemOpt3
ADD FILEGROUP DbMemOpt3_mod_memopt_1_fg
CONTAINS MEMORY_OPTIMIZED_DATA;
GO
-- Change the FILENAME path to where your DATA subdirectory is located,
-- keeping only the trailing portion '\DATA\DbMemOpt3_mod_memopt_1_fn'.
ALTER DATABASE DbMemOpt3
ADD FILE (
NAME = 'DbMemOpt3_mod_memopt_1_name',
FILENAME = 'C:\DATA\DbMemOpt3_mod_memopt_1_fn'
)
TO FILEGROUP DbMemOpt3_mod_memopt_1_fg;
GO
USE DbMemOpt3;
GO
CREATE TABLE dbo.t1
(
c1 INT NOT NULL PRIMARY KEY NONCLUSTERED,
c2 INT
)
WITH (MEMORY_OPTIMIZED = ON);
GO
-- Retrieve the path of the DLL for table t1.
DECLARE @moduleName AS NVARCHAR (256);
SET @moduleName = ('%xtp_t_'
+ CAST (db_id() AS NVARCHAR (16))
+ '_' + CAST (object_id('dbo.t1') AS NVARCHAR (16))
+ '%.dll');
-- Search for the name: mod1.name LIKE '%xtp_t_8_565577053%.dll'
PRINT @moduleName;
SELECT mod1.name,
mod1.description
FROM sys.dm_os_loaded_modules AS mod1
WHERE mod1.name LIKE @moduleName
ORDER BY mod1.name;
GO
-- Clean up.
-- DROP DATABASE DbMemOpt3;
-- GO
建立資料表也會建立資料表 DLL 並將 DLL 載入記憶體中。 緊接在 CREATE TABLE 陳述式之後的 DMV 查詢會擷取資料表 DLL 的路徑。
資料表 DLL 能夠辨識資料表的索引結構和資料列格式。 資料庫引擎 使用 DLL 來遍歷索引、檢索資料列,以及儲存資料列內容。
儲存程序的原生編譯
將儲存程序標記為 NATIVE_COMPILATION,以便將其原生編譯。 程序中的 Transact-SQL 語句皆編譯為原生程式碼,以有效執行對效能至關重要的商業邏輯。
欲了解更多關於原生編譯的儲存程序,請參閱《 Memory-Optimized 資料表查詢處理指南》。
以下範例預存程序會將資料列插入前一個範例中的資料表 t1:
CREATE PROCEDURE dbo.native_sp
WITH NATIVE_COMPILATION, SCHEMABINDING, EXECUTE AS OWNER
AS
BEGIN ATOMIC
WITH (TRANSACTION ISOLATION LEVEL = SNAPSHOT, LANGUAGE = N'us_english')
DECLARE @i AS INT = 1000000;
WHILE @i > 0
BEGIN
INSERT dbo.t1
VALUES (@i, @i + 1);
SET @i -= 1;
END
END;
GO
EXECUTE dbo.native_sp;
GO
-- Reset.
DELETE dbo.t1;
GO
DLL native_sp 可直接與 的 t1DLL 互動,並與記憶體內的 OLTP 儲存引擎互動,以盡可能快速地插入資料列。 查詢優化器為儲存程序中的每個查詢建立一個高效的執行計畫。
原生編譯的儲存程序在資料表中資料變更時不會自動重新編譯。 如需更多有關使用記憶體內部 OLTP 維護統計資料和預存程序的資訊,請參閱 記憶體最佳化資料表的統計資料。
原生編譯的安全考量
表格與儲存程序的原生編譯使用記憶體內的 OLTP 編譯器。 編譯器產生的檔案會寫入磁碟並載入記憶體。 資料庫引擎 使用以下機制來限制對這些檔案的存取權限。
編譯器
編譯器執行檔、二進位檔及標頭檔案作為 資料庫引擎 實例的一部分安裝於MSSQL\Binn\Xtp資料夾 下。 如果你在 下安裝預設實例 C:\Program Files,編譯器檔案會在 C:\Program Files\Microsoft SQL Server\MSSQL\<version>.MSSQLSERVER\MSSQL\Binn\Xtp。
為了限制對編譯器的存取,資料庫引擎 使用存取控制清單(ACL)來限制對二進位檔案的存取。 ACL 保護所有 資料庫引擎 二進位檔,防止被修改或竄改。 原生編譯器的 ACL 也限制了編譯器的使用;只有 資料庫引擎 服務帳號與系統管理員擁有本地編譯器檔案的讀取與執行權限。
由原生編譯產生的檔案
編譯資料表或預存程序時所產生的檔案包括 DLL 和中繼檔案,其中包含具有下列副檔名的檔案:.c、.obj、.xml 及 .pdb。 產生的檔案會儲存在預設資料夾中的 xtp 子資料夾內,而該預設資料夾在 SERVERPROPERTY 中定義為 InstanceDefaultDataPath。 一個範例檔案路徑為: C:\Program Files\Microsoft SQL Server\MSSQL\<version>.MSSQLSERVER\MSSQL\DATA\Xtp。
資料庫引擎 透過三種方式防止對產生的 DLL 進行竄改:
當資料表或儲存程序編譯成 DLL 時,DLL 會立即載入記憶體,並與程序
sqlserver.exe連結。 當 DLL 已連結至某個處理程序時,你無法修改它。當資料庫重新啟動時,所有資料表和儲存程序會從資料庫中繼資料重新編譯(即移除並重建),儲存程序會在首次執行時編譯。 重新編譯會捨棄對產生檔案所做的任何更改,例如惡意行為者篡改。
產生的檔案被視為使用者資料,並透過存取控制權(ACL)受到與資料庫檔案相同的安全限制。 只有 資料庫引擎 服務帳號和系統管理員能存取這些檔案。
你不需要管理這些檔案。 資料庫引擎 會根據需要建立和移除檔案。