テーブルとストアド プロシージャのネイティブ コンパイル

適用対象:yesSQL Server (サポートされているすべてのバージョン) Yes Azure SQL Database

インメモリ OLTP により、ネイティブ コンパイルという概念が導入されています。 SQL Server は、メモリ最適化テーブルにアクセスするストアドプロシージャをネイティブにコンパイルできます。 SQL Server は、メモリ最適化テーブルをネイティブにコンパイルすることもできます。 ネイティブコンパイルは、解釈された (従来の) Transact-sql SQL よりも高速なデータアクセスと効率的なクエリ実行を可能にします。 テーブルとストアド プロシージャのネイティブ コンパイルを実行すると DLL が生成されます。

メモリ最適化テーブル型のネイティブ コンパイルもサポートされています。 詳細については、「 Faster temp table and table variable by using memory optimization」 (メモリ最適化を使用した一時テーブルとテーブル変数の高速化) を参照してください。

ネイティブ コンパイルとは、プログラミングの構造をネイティブ コードに変換する処理であり、追加のコンパイルまたは解釈を必要としないプロセッサ命令で構成されます。

インメモリ OLTP は、作成されたときにメモリ最適化テーブルを、そしてネイティブ DLL に読み込まれたときにネイティブ コンパイル ストアド プロシージャをコンパイルします。 また、DLL は、データベースまたはサーバーが再起動した後に再コンパイルされます。 DLL を再作成するために必要な情報がデータベース メタデータに格納されます。 DLL は、データベースに関連付けられていますが、データベースの一部ではありません。 たとえば、DLL は、データベース バックアップに含まれていません。

Note

メモリ最適化テーブルは、サーバーの再起動中に再コンパイルされます。 データベースの復元を迅速に行うために、ネイティブ コンパイル ストアド プロシージャは、サーバーの再起動中に再コンパイルされず、最初の実行時にコンパイルされます。 この遅延コンパイルの結果、ネイティブコンパイルストアドプロシージャは、最初の実行後にsys.dm_os_loaded_modules (Transact SQL)を呼び出すときにのみ表示されます。

インメモリ OLTP DLL のメンテナンス

次のクエリは、サーバーのメモリに現在読み込まれているすべてのテーブルとストアド プロシージャ DLL を示します。

SELECT
		mod1.name,
		mod1.description
	from
		sys.dm_os_loaded_modules  as mod1
	where
		mod1.description = 'XTP Native DLL';

ネイティブ コンパイルによって生成されたファイルをデータベース管理者が維持する必要はありません。 SQL Server は、不要になった生成されたファイルを自動的に削除します。 たとえばテーブルやストアド プロシージャが削除されたとき、またはデータベースが削除されたときに、生成ファイルが削除されます。

Note

コンパイルが失敗するか、中断した場合、生成されたファイルの一部は削除されません。 これらのファイルはサポート性のために意図的に残され、データベースが削除されるときに削除されます。

Note

SQL Server によってデータベースの復旧に必要なすべてのテーブルの DLL がコンパイルされます。 データベースを再起動する直前にテーブルが削除された場合、チェックポイント ファイルかトランザクション ログにテーブルの残存物が存在するため、データベースの起動中にテーブルの DLL が再コンパイルされる場合があります。 再起動後に DLL がアンロードされ、通常のクリーンアップ プロセスによってファイルが削除されます。

テーブルのネイティブ コンパイル

CREATE TABLE ステートメントを使用してメモリ最適化テーブルを作成すると、テーブル情報がデータベース メタデータに書き込まれ、テーブルとインデックス構造がメモリに作成されます。 また、テーブルは DLL にコンパイルされます。

データベースとメモリ最適化テーブルを作成する、次のサンプル スクリプトについて考えてみます。

USE master;
GO

CREATE DATABASE DbMemopt3;
GO

ALTER DATABASE DbMemopt3
	add filegroup DbMemopt3_mod_memopt_1_fg
		contains memory_optimized_data
;
GO

-- You must edit the front portion of filename= path, to where your DATA\ subdirectory is,
-- 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'

		--filename = 'C:\Program Files\Microsoft SQL Server\MSSQL13.SQLSVR2016ID\MSSQL\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



-- You can safely rerun from here to the end.

-- Retrieve the path of the DLL for table t1.


DECLARE @moduleName  nvarchar(256);

SET @moduleName =
	(
		'%xtp_t_' +
		cast(db_id() as nvarchar(16)) +
		'_' +
		cast(object_id('dbo.t1') as nvarchar(16)) +
		'%.dll'
	)
;


-- SEARCHED FOR NAME EXAMPLE:  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
;
-- ACTUAL NAME EXAMPLE:  mod1.name = 'C:\Program Files\Microsoft SQL Server\MSSQL13.SQLSVR2016ID\MSSQL\DATA\xtp\8\xtp_t_8_565577053_184009305855461.dll'
GO

--   DROP DATABASE DbMemopt3;  -- Clean up.
GO

テーブルを作成すると、テーブル DLL が作成され、メモリに DLL が読み込まれます。 CREATE TABLE ステートメントの直後の DMV クエリは、テーブル DLL のパスを取得します。

テーブル DLL は、テーブルのインデックス構造と行形式を理解します。 SQL Server は、DLL を使用してインデックスを走査したり、行を取得したり、行の内容を格納したりします。

ストアド プロシージャのネイティブ コンパイル

NATIVE_COMPILATION が設定されているストアド プロシージャはネイティブでコンパイルされます。 つまり、プロシージャ内の SQL transact-sql ステートメントがすべてネイティブコードにコンパイルされ、パフォーマンスクリティカルなビジネスロジックを効率的に実行できるようになります。

ネイティブ コンパイル ストアド プロシージャの詳細については、「 Natively Compiled Stored Procedures」をご覧ください。

前の例のテーブル 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 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 from dbo.t1;
GO

行をできる限り高速に挿入するために、native_sp の DLL は t1 の DLL およびインメモリ OLTP ストレージ エンジンと直接やり取りできます。

インメモリ OLTP コンパイラは、ストアド プロシージャの各クエリに有効な実行プランを作成するためにクエリ オプティマイザーを活用します。 テーブルのデータが変更された場合はネイティブ コンパイル ストアド プロシージャは自動的に再コンパイルされないことに注意してください。 インメモリ OLTP の統計とストアド プロシージャの管理の詳細については、「 メモリ最適化テーブルの統計」を参照してください。

ネイティブ コンパイルにおけるセキュリティの注意点

テーブルおよびストアド プロシージャのネイティブ コンパイルでは、インメモリ OLTP コンパイラを使用します。 このコンパイラはファイルを生成し、そのファイルがディスクに書き込まれて、メモリに読み込まれます。 SQL Server は、次のメカニズムを使用して、これらのファイルへのアクセスを制限します。

ネイティブ コンパイラ

コンパイラの実行可能ファイル、およびネイティブコンパイルに必要なバイナリおよびヘッダーファイルは、SQL Server インスタンスの一部として mssql\binn\xtp フォルダーにインストールされます。 そのため、既定のインスタンスが C:\Program Files の下にインストールされている場合、コンパイラファイルは C:\Program Files\MicrosoftSQL Server\MSSQL13. にインストールされます。MSSQLSERVER\MSSQL\Binn\Xtp.

コンパイラへのアクセスを制限するために、SQL Server はアクセス制御リスト (acl) を使用して、バイナリファイルへのアクセスを制限します。 すべての SQL Server バイナリは、acl による変更や改ざんから保護されます。 また、ネイティブコンパイラの Acl では、コンパイラの使用も制限されています。ネイティブコンパイラファイルに対する読み取りと実行のアクセス許可は、SQL Server サービスアカウントとシステム管理者のみに与えられています。

ネイティブ コンパイルによって生成されるファイル

テーブルまたはストアド プロシージャのコンパイル時に生成されるファイルには、DLL のほか、.c、.obj、.xml、.pdb などの拡張子を持つ中間ファイルがあります。 生成されたファイルは、既定のデータ フォルダーのサブフォルダーに保存されます。 サブフォルダーは Xtp と呼ばれます。 既定のデータフォルダーを使用して既定のインスタンスをインストールする場合、生成されたファイルは C:\Program Files\MicrosoftSQL Server\MSSQL13. に配置されます。MSSQLSERVER\MSSQL\DATA\Xtp.

SQL Server は、次の3つの方法で生成された dll の改ざんを防止します。

  • テーブルまたはストアド プロシージャが DLL にコンパイルされると、この DLL は直ちにメモリに読み込まれ、sqlserver.exe プロセスにリンクされます。 プロセスにリンクされている間、その DLL は変更できません。

  • データベースを再起動すると、データベースのメタデータに基づいて、すべてのテーブルとストアド プロシージャが再コンパイル (削除後、再作成) されます。 これにより、生成されたファイルに対して悪意のあるエージェントによって行われた変更があれば、すべて削除されます。

  • 生成されたファイルはユーザーデータの一部と見なされ、acl を介して、データベースファイルと同じセキュリティ制限があります。これらのファイルにアクセスできるのは、SQL Server サービスアカウントとシステム管理者だけです。

これらのファイルの管理には、ユーザー操作は不要です。 SQL Server は、必要に応じてファイルを作成および削除します。

参照

メモリ最適化テーブル

ネイティブ コンパイル ストアド プロシージャ