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

適用対象:SQL ServerAzure SQL データベースAzure SQL Managed Instance

インメモリ オンライン トランザクション処理 (OLTP) は、ネイティブ コンパイルを使用して、解釈された (従来の) Transact-SQLよりも高速なデータ アクセスと効率的なクエリ実行を提供します。 テーブルとストアド プロシージャのネイティブ コンパイルでは、 ダイナミック リンク ライブラリ (DLL) が生成されます。

SQL Server データベース エンジンでは、メモリ最適化テーブル、メモリ最適化テーブルにアクセスするストアド プロシージャ、およびメモリ最適化テーブルの種類をネイティブにコンパイルできます。 詳細については、「 Faster temp table and table variable by using memory optimization」 (メモリ最適化を使用した一時テーブルとテーブル変数の高速化) を参照してください。

インメモリ 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

native_sp用の DLL は、t1用の DLL と直接やり取りでき、インメモリ OLTP ストレージ エンジンを使用して、できるだけ高速に行を挿入できます。 クエリ オプティマイザーは、ストアド プロシージャ内の各クエリに対して効率的な実行プランを作成します。

テーブル内のデータが変更されても、ネイティブ コンパイル ストアド プロシージャは自動的に再コンパイルされません。 インメモリ OLTP を使用した統計とストアド プロシージャの保守の詳細については、「 Memory-Optimized テーブルの統計」を参照してください。

ネイティブ コンパイルのセキュリティに関する考慮事項

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

コンパイラ

ネイティブ コンパイルに必要なコンパイラ実行可能ファイル、バイナリ ファイル、およびヘッダー ファイルは、データベース エンジン インスタンスの一部として、フォルダー MSSQL\Binn\Xtpの下にインストールされます。 C:\Program Filesの下に既定のインスタンスをインストールすると、コンパイラ ファイルはC:\Program Files\Microsoft SQL Server\MSSQL\<version>.MSSQLSERVER\MSSQL\Binn\Xtp

コンパイラへのアクセスを制限するために、データベース エンジンはアクセス制御リスト (ACL) を使用してバイナリ ファイルへのアクセスを制限します。 ACL は、変更や改ざんからすべてのデータベース エンジン バイナリを保護します。 ネイティブ コンパイラの ACL では、コンパイラの使用も制限されます。ネイティブ コンパイラ ファイルの読み取りと実行のアクセス許可を持つのは、データベース エンジン サービス アカウントとシステム管理者だけです。

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

テーブルまたはストアド プロシージャのコンパイル時に生成されるファイルには、拡張子が .c.obj.xml.pdb のファイルを含む DLL ファイルと中間ファイルが含まれます。 生成されたファイルは、xtpInstanceDefaultDataPathとして定義されている既定のデータ フォルダーのサブフォルダーに保存されます。 ファイル パスの例は、 C:\Program Files\Microsoft SQL Server\MSSQL\<version>.MSSQLSERVER\MSSQL\DATA\Xtpです。

データベース エンジンは、生成された DLL の改ざんを 3 つの方法で防止します。

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

  • データベースが再起動すると、すべてのテーブルとストアド プロシージャがデータベース メタデータから再コンパイル (つまり、削除および再作成) され、ストアド プロシージャは最初の実行時にコンパイルされます。 再コンパイルでは、悪意のあるエージェントによる改ざんなど、生成されたファイルに加えられたすべての変更が破棄されます。

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

これらのファイルを管理する必要はありません。 データベース エンジンは、必要に応じてファイルを作成および削除します。