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

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

メモリ最適化テーブル型のネイティブ コンパイルもサポートされています。 詳しくは、「 Memory-Optimized Table Variables」をご覧ください。

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

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

Note

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

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

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

SELECT name, description FROM sys.dm_os_loaded_modules  
where description = 'XTP Native DLL'  

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

Note

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

Note

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

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

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

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

use master  
go  
create database db1  
go  
alter database db1 add filegroup db1_mod contains memory_optimized_data  
go  
-- adapt filename as needed  
alter database db1 add file (name='db1_mod', filename='c:\data\db1_mod') to filegroup db1_mod  
go  
use db1  
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  
select name, description FROM sys.dm_os_loaded_modules  
where name like '%xtp_t_' + cast(db_id() as varchar(10)) + '_' + cast(object_id('dbo.t1') as varchar(10)) + '.dll'  
go  

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

テーブル DLL は、テーブルのインデックス構造と行形式を理解します。 SQL Server は DLL を使用してインデックスをスキャンし、行を取得し、行のコンテンツを格納します。

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

NATIVE_COMPILATION が設定されているストアド プロシージャはネイティブでコンパイルされます。 つまり、プロシージャ内の 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  
exec 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\MSSQL12 にインストールされます。MSSQLSERVER\MSSQL\Binn\Xtp。

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

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

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

SQL Server は 3 とおりの方法で、生成した DLL に対する改ざんを回避します。

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

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

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

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

参照

メモリ最適化テーブル
ネイティブ コンパイル ストアド プロシージャ