メモリ最適化テーブル変数Memory-Optimized Table Variables

メモリ最適化テーブル (効率的なデータ アクセスのため) とネイティブ コンパイル ストアド プロシージャ (効率的なクエリ処理とビジネス ロジックの実行のため) に加えて、-インメモリ OLTPIn-Memory OLTP では、3 つ目のオブジェクトの種類としてメモリ最適化テーブル型が導入されます。In addition to memory-optimized tables (for efficient data access) and natively compiled stored procedures (for efficient query processing and business logic execution) -インメモリ OLTPIn-Memory OLTP introduces a third kind of object: the memory-optimized table type. メモリ最適化テーブル型を使用して作成されたテーブル変数は、メモリ最適化テーブル変数です。A table variable created using a memory-optimized table type is a memory-optimized table variable.

メモリ最適化テーブル変数には、ディスク ベース テーブル変数と比べて次の利点があります。Memory-optimized table variables offer the following advantages when compared to disk-based table variables:

  • 変数はメモリにしか格納されません。The variables are only stored in memory. メモリ最適化テーブル型では、メモリ最適化テーブルで使用されるものと同じメモリ最適化アルゴリズムとデータ構造が使用されるため、データ アクセスがさらに効率的になります。特に、変数をネイティブ コンパイル ストアド プロシージャで使用するときに効率的です。Data access is more efficient because memory-optimized table type use the same memory-optimized algorithm and data structures used for memory-optimized tables, especially when the variables are used in natively compiled stored procedures.

  • メモリ最適化テーブル変数を使用する場合、tempdb は使用しません。With memory-optimized table variables, there is no tempdb utilization. テーブル変数は tempdb に保存されず、tempdb 内のリソースを使用しません。Table variables are not stored in tempdb and do not use any resources in tempdb.

メモリ最適化テーブル変数の一般的な使用シナリオは次のとおりです。The typical usage scenarios for memory-optimized table variables are:

  • 中間結果を保存し、ネイティブ コンパイル ストアド プロシージャの複数のクエリに基づいて単一の結果セットを作成します。Storing intermediate results and creating single result sets based on multiple queries in natively compiled stored procedures.

  • ネイティブ コンパイル ストアド プロシージャおよびインタープリターで処理されるストアド プロシージャに、テーブル値パラメーターを渡します。Passing table-valued parameters into natively compiled stored procedures and interpreted stored procedures.

  • ディスク ベース テーブル変数を置き換え、場合によっては、ストアド プロシージャに対してローカルな #temp テーブルを置き換えます。Replacing disk-based table variables, and in some cases #temp tables that are local to a stored procedure. これは、システムに多くの tempdb の競合がある場合に特に便利です。This is particularly useful if there is a lot of tempdb contention in the system.

  • テーブル変数を使用して、ネイティブ コンパイル ストアド プロシージャのカーソルをシミュレートすることができ、その結果、ネイティブ コンパイル ストアド プロシージャの対象領域の制限を回避できるようになります。Table variables can be used to simulate cursors in natively compiled stored procedures, which can help you work around surface area limitations in natively compiled stored procedures.

メモリ最適化テーブルと同様に、 SQL ServerSQL Server によってメモリ最適化テーブル型ごとに DLL が生成されますLike memory-optimized tables, SQL ServerSQL Server generates a DLL for each memory-optimized table type. (コンパイルは、ときではなく、メモリ最適化テーブル変数を作成するために使用し、メモリ最適化テーブル型が作成されたときに呼び出されます)。この DLL には、インデックスにアクセスし、テーブル変数からデータを取得するための関数が含まれます。(Compilation is invoked when the memory-optimized table type is created and not when used to create memory-optimized table variables.) This DLL includes the functions for accessing indexes and retrieving data from the table variables. メモリ最適化テーブル変数がテーブル型に基づいて宣言されると、テーブルとテーブル型に対応するインデックス構造のインスタンスがユーザー セッションで作成されます。When a memory-optimized table variable is declared based on the table type, an instance of the table and index structures corresponding to the table type is created in the user session. その後、テーブル変数をディスク ベース テーブル変数と同じ方法で使用できます。The table variable can then be used in the same way as disk-based table variables. テーブル変数の行を挿入、更新、および削除でき、 Transact-SQLTransact-SQL クエリで変数を使用できます。You can insert, update, and delete rows in the table variable, and you can use the variables in Transact-SQLTransact-SQL queries. また、ネイティブ コンパイル ストアド プロシージャと、インタープリターによって処理されるストアド プロシージャに、テーブル値パラメーター (TVP) として変数を渡すことができます。You can also pass the variables into natively compiled and interpreted stored procedures, as table-valued parameters (TVP).

次の例では、AdventureWorks に基づくインメモリ OLTP のサンプルからメモリ最適化テーブル型 (SQL Server 2014 のインメモリ OLTP のサンプル)。The following sample shows a memory-optimized table type from the AdventureWorks-based In-Memory OLTP sample (SQL Server 2014 In-Memory OLTP Sample).

CREATE TYPE Sales.SalesOrderDetailType_inmem
   AS TABLE
(
   OrderQty         smallint   NOT NULL,
   ProductID        int        NOT NULL,

   SpecialOfferID   int        NOT NULL
      INDEX  IX_SpecialOfferID  NONCLUSTERED,

   LocalID          int        NOT NULL,

   INDEX IX_ProductID HASH (ProductID)
      WITH ( BUCKET_COUNT = 8 )
)
WITH ( MEMORY_OPTIMIZED = ON );

このサンプルは、メモリ最適化テーブル型の構文がディスク ベース テーブル型に類似していることを示しています。ただし、次の例外を除きます。The sample shows that the syntax of memory-optimized table types is similar to disk-based table types, with the following exceptions:

  • MEMORY_OPTIMIZED=ON は、テーブル型がメモリ最適化であることを示します。MEMORY_OPTIMIZED=ON indicates that the table type is memory-optimized.

  • 型には少なくとも 1 つのインデックスが必要です。The type must have at least one index. メモリ最適化テーブルの場合と同様に、ハッシュ インデックスと非クラスター化インデックスを使用できます。As with memory-optimized tables, you can use hash and nonclustered indexes.

    ハッシュ インデックスの場合、バケット数は予想される一意のキーの数からその 2 倍の数ぐらいまでの範囲にしてください。For a hash index, the bucket count should be about one to two times the number of expected unique index keys. 詳細については、「 Determining the Correct Bucket Count for Hash Indexes」を参照してください。For more information, see Determining the Correct Bucket Count for Hash Indexes.

  • メモリ最適化テーブルのデータ型および制約の制限は、メモリ最適化テーブル型にも適用されます。The data type and constraint restrictions on memory-optimized tables also apply to memory-optimized table types. たとえば、SQL Server 2014SQL Server 2014 では既定の制約はサポートされますが、CHECK 制約はサポートされません。For example, in SQL Server 2014SQL Server 2014 default constraints are supported, but check constraints are not.

メモリ最適化テーブルと同様に、メモリ最適化テーブル変数には次のことが当てはまります。Like memory-optimized tables, memory-optimized table variables,

  • 並列プランはサポートされません。Do not support parallel plans.

  • メモリに収まる必要があるため、ディスク リソースを使用しません。Must fit in memory and do not use disk resources.

ディスク ベース テーブル変数は tempdb 内に存在します。Disk-based table variables exist in tempdb. メモリ最適化テーブル変数は、ユーザー データベース内に存在します (ただし、ストレージを消費せず、復旧もされません)。Memory-optimized table variables exist in the user database (but they do not consume storage and are not recovered).

インライン構文を使用して、メモリ最適化テーブル変数を作成することはできません。You cannot create a memory-optimized table variable using in-line syntax. ディスク ベース テーブル変数とは異なり、最初に型を作成する必要があります。Unlike disk-based table variables, you must create a type first.

テーブル値パラメーターTable-Valued Parameters

次のサンプル スクリプトでは、メモリ最適化テーブル型 Sales.SalesOrderDetailType_inmem としてテーブル変数を宣言し、変数に 3 つの行を挿入し、変数を TVP として Sales.usp_InsertSalesOrder_inmem に渡します。The following sample script shows the declaration of a table variable as the memory-optimized table type Sales.SalesOrderDetailType_inmem, the insert of three rows into the variable, and passing the variable as a TVP into Sales.usp_InsertSalesOrder_inmem.

DECLARE @od Sales.SalesOrderDetailType_inmem,  
  @SalesOrderID uniqueidentifier,  
  @DueDate datetime2 = SYSDATETIME()  
  
INSERT @od (LocalID, ProductID, OrderQty, SpecialOfferID) VALUES  
  (1, 888, 2, 1),  
  (2, 450, 13, 1),  
  (3, 841, 1, 1)  
  
EXEC Sales.usp_InsertSalesOrder_inmem  
  @SalesOrderID = @SalesOrderID,  
  @DueDate = @DueDate,  
 @OnlineOrderFlag = 1,  
  @SalesOrderDetails = @od  

メモリ最適化テーブル型は、ストアド プロシージャのテーブル値パラメーター (TVP) の型として使用でき、ディスク ベース テーブル型および TVP とまったく同じようにクライアントから参照できます。Memory-optimized table types can be used as the type for stored procedure table-valued parameters (TVPs) and can be referenced by clients exactly the same as disk-based table types and TVPs. したがって、メモリ最適化 TVP が含まれるストアド プロシージャ、およびネイティブ コンパイル ストアド プロシージャの呼び出しは、ディスク ベース TVP が含まれる、インタープリターによって解釈されるストアド プロシージャの呼び出しとまったく同じように動作します。Therefore, the invocation of stored procedures with memory-optimized TVPs, and natively compiled stored procedures works exactly the same as the invocation of interpreted stored procedures with disk-based TVPs.

#temp テーブルの置換#temp Table Replacement

次のサンプルは、ストアド プロシージャに対してローカルな #temp のテーブルの代わりとしてのメモリ最適化テーブル型およびテーブル変数を示しています。The following sample shows memory-optimized table types and table variables as a replacement for #temp tables that are local to a stored procedure.

-- Using SQL procedure and temp table  
CREATE TABLE #tempTable (c INT NOT NULL PRIMARY KEY NONCLUSTERED)  
  
CREATE PROCEDURE sqlProc  
AS  
BEGIN  
  TRUNCATE TABLE #tempTable  
  
  INSERT #tempTable VALUES (1)  
  INSERT #tempTable VALUES (2)  
  INSERT #tempTable VALUES (3)  
  SELECT * FROM #tempTable  
END  
GO  
  
-- Using natively compiled stored procedure and table variable  
CREATE TYPE TT AS TABLE (c INT NOT NULL PRIMARY KEY NONCLUSTERED)  
GO  
  
CREATE PROCEDURE NCSPProc  
WITH NATIVE_COMPILATION, SCHEMABINDING, EXECUTE AS OWNER  
AS  
BEGIN ATOMIC WITH (TRANSACTION ISOLATION LEVEL = SNAPSHOT, LANGUAGE = N'us_english')  
  DECLARE @tableVariable TT  
  INSERT @tableVariable VALUES (1)  
  INSERT @tableVariable VALUES (2)  
  INSERT @tableVariable VALUES (3)  
  SELECT c FROM @tableVariable  
END  
GO  

単一結果セットの作成Creating a Single Result Set

次のサンプルでは、中間結果を保存し、ネイティブ コンパイル ストアド プロシージャの複数のクエリに基づいて単一の結果セットを作成する方法を示します。The following sample shows how to store intermediate results and create single result sets based on multiple queries in natively compiled stored procedures. ここでは、UNION 演算子を使用した SELECT c1 FROM dbo.t1 UNION SELECT c1 FROM dbo.t2 を計算しています。The sample is computing the union SELECT c1 FROM dbo.t1 UNION SELECT c1 FROM dbo.t2.

CREATE DATABASE hk  
GO  
ALTER DATABASE hk ADD FILEGROUP hk_mod CONTAINS MEMORY_OPTIMIZED_DATA  
ALTER DATABASE hk ADD FILE( NAME = 'hk_mod' , FILENAME = 'c:\data\hk_mod') TO FILEGROUP hk_mod;  
  
USE hk  
GO  
  
CREATE TYPE tab1 AS TABLE (c1 INT NOT NULL, INDEX idx NONCLUSTERED(c1)) WITH (MEMORY_OPTIMIZED = ON)  
  
CREATE TABLE dbo.t1 (c1 INT NOT NULL, INDEX idx NONCLUSTERED(c1)) WITH (MEMORY_OPTIMIZED = ON, DURABILITY = SCHEMA_ONLY)  
CREATE TABLE dbo.t2 (c1 INT NOT NULL, INDEX idx NONCLUSTERED(c1)) WITH (MEMORY_OPTIMIZED = ON, DURABILITY = SCHEMA_ONLY)  
  
INSERT INTO dbo.t1 VALUES (1), (2)  
INSERT INTO dbo.t2 VALUES (3), (4)  
GO  
  
CREATE PROCEDURE dbo.p1  
  WITH NATIVE_COMPILATION, SCHEMABINDING, EXECUTE AS OWNER  
  AS  
  BEGIN ATOMIC WITH ( TRANSACTION ISOLATION LEVEL = SNAPSHOT, LANGUAGE = N'us_english' )  
  
    DECLARE @t dbo.tab1  
    INSERT @t (c1)  
    SELECT c1 FROM dbo.t1;  
  
    INSERT @t (c1)  
    SELECT c1 FROM dbo.t2;  
  
    SELECT c1 FROM @t;  
  END  
GO  
  
EXEC dbo.p1  
GO  

テーブル変数によるメモリ消費Memory Consumption for Table Variables

テーブル変数によるメモリ消費は、非クラスター化インデックスを除き、メモリ最適化テーブルに似ています。Memory consumption for table variables is similar to memory-optimized tables, with the exception of nonclustered indexes. 非クラスター化インデックスを使用してメモリ最適化テーブル変数に多数の行を挿入する場合に、インデックス キーが大きいと、これらのテーブル変数では過剰な量のメモリが使用されます。If you insert a lot of rows into memory-optimized table variables with nonclustered indexes and if the index keys are large, these table variables will use a disproportionate amount of memory. 大きなテーブル変数を対象とする非クラスター化インデックスは、非クラスター化インデックス テーブルが同じ数の行を挿入する場合に比べて多くのメモリ (インデックス ページ内のより多くメモリ) を必要とします。Nonclustered indexes on large table variables require proportionately more memory than a nonclustered index would require for the same number of rows inserted into a table (more memory in the index pages).

テーブル変数のメモリは、データベースのリソース ガバナー リソース プールから取得されます。Memory for table variables comes from the database's Resource Governor resource pool.

メモリ最適化テーブルとは異なり、テーブル変数によって消費された (削除された行を含む) メモリは、テーブル変数がスコープ外になると解放されます。Unlike memory-optimized tables, the memory consumed (including deleted rows) by table variables is freed when the table variable goes out of scope.

メモリは、データベースの単一 PGPOOL メモリ コンシューマーの一部として説明されます。Memory is accounted for as part of the single PGPOOL memory consumer of the database.

関連項目See Also

Transact-SQL によるインメモリ OLTP のサポートTransact-SQL Support for In-Memory OLTP