メモリ最適化テーブルの変更

適用対象:SQL ServerAzure SQL DatabaseAzure SQL Managed Instance

メモリ最適化テーブルのスキーマとインデックスの変更は、 ALTER TABLE ステートメントを使用して実行できます。 SQL Server 2016 およびメモリ最適化テーブルに対するAzure SQL Database ALTER TABLE操作は OFFLINE です。つまり、操作の進行中はテーブルをクエリに使用できません。 データベース アプリケーションは実行を継続できます。また、テーブルにアクセスする操作は、変更プロセスが完了するまでブロックされます。 1 つの ALTER TABLE ステートメントで複数の ADD、DROP、または ALTER 操作を組み合わせることができます。

重要

Azure SQL Managed Instance では、General Purpose サービス レベルでのメモリ最適化テーブルはサポートされません。

ALTER TABLE

ALTER TABLE構文は、テーブル スキーマを変更したり、インデックスを追加、削除、再構築したりするために使用されます。 インデックスは、テーブル定義の一部と見なされます。

  • 構文 ALTER TABLE ...ADD/DROP/ALTER INDEX は、メモリ最適化テーブルでのみサポートされます。

  • ALTER TABLE ステートメントを使用しない場合、ステートメントCREATE INDEXDROP INDEXALTER INDEXおよびPAD_INDEXは、メモリ最適化テーブルのインデックスではサポートされません。

次の種類の変更がサポートされています。

  • バケット数の変更

  • インデックスの追加と削除

  • 列の変更、追加、削除

  • 制約の追加と削除

ALTER TABLE機能と完全な構文の詳細については、ALTER TABLE (Transact-SQL) を参照してください。

スキーマ バインド依存関係

スキーマ バインドであるためには、アクセスするメモリ最適化テーブルおよび参照する列に対するスキーマ バインド依存関係を持つネイティブ コンパイル ストアド プロシージャが必要です。 スキーマ バインド依存関係とは、参照元エンティティが存在する限り、参照先エンティティを削除したり、互換性のない方法で変更したりすることができない 2 つのエンティティ間のリレーションシップです。

たとえば、スキーマ バインドのネイティブ コンパイル ストアド プロシージャがテーブル mytable の列 c1を参照している場合、列 c1 は削除できません。 同様に、列リストのない INSERT ステートメント (例: INSERT INTO dbo.mytable VALUES (...)) を含むプロシージャがある場合、テーブル内の列は削除できません。

メモリ最適化テーブルでの ALTER TABLE のログ記録

メモリ最適化テーブルでは、ほとんどの ALTER TABLE シナリオが並列で実行され、トランザクション ログへの書き込みが最適化されるようになりました。 最適化は、メタデータの変更のみをトランザクション ログに記録することによって実現されます。 ただし、次の ALTER TABLE 操作はシングル スレッドで実行され、ログ最適化されません。

この場合のシングル スレッド操作は、変更されたテーブルの内容全体をトランザクション ログに記録します。 シングル スレッド操作の一覧を以下に示します。

  • nvarchar(max)、varchar(max)、varbinary(max) などのラージ オブジェクト (LOB) 型を使用するために列を変更または追加します。

  • COLUMNSTORE インデックスを追加または削除します。

  • 行外列に影響するほぼあらゆる操作。

    • 行内の列を行外に移動します。
    • 行外の列を行内に移動します。
    • 新しい行外の列を作成します。
    • 例外: 既存の行外列が長くなった場合は、最適化された方法でログに記録されます。

次の例では、既存のハッシュ インデックスのバケット数を変更します。 その結果、新しいバケット数でハッシュ インデックスが再構築されますが、ハッシュ インデックスの他のプロパティは変わりません。

ALTER TABLE Sales.SalesOrderDetail_inmem
       ALTER INDEX imPK_SalesOrderDetail_SalesOrderID_SalesOrderDetailID  
              REBUILD WITH (BUCKET_COUNT=67108864);  
GO

次の例では、NOT NULL 制約と DEFAULT 定義を持つ列を追加し、WITH VALUES を使用してテーブル内の既存の行ごとに値を指定します。 WITH VALUES を使用しない場合、新しい列には NULL 値が格納されます。

ALTER TABLE Sales.SalesOrderDetail_inmem  
       ADD Comment NVARCHAR(100) NOT NULL DEFAULT N'' WITH VALUES;  
GO

次の例では、プライマリ キー制約を既存の列に追加します。

CREATE TABLE dbo.UserSession (
   SessionId int not null,
   UserId int not null,
   CreatedDate datetime2 not null,
   ShoppingCartId int,
   index ix_UserId nonclustered hash (UserId) with (bucket_count=400000)
)
WITH (MEMORY_OPTIMIZED=ON, DURABILITY=SCHEMA_ONLY) ;  
GO  
  
ALTER TABLE dbo.UserSession  
       ADD CONSTRAINT PK_UserSession PRIMARY KEY NONCLUSTERED (SessionId);  
GO

次の例では、インデックスを削除します。

ALTER TABLE Sales.SalesOrderDetail_inmem  
       DROP INDEX ix_ModifiedDate;  
GO

次の例では、インデックスを追加します。

ALTER TABLE Sales.SalesOrderDetail_inmem  
       ADD INDEX ix_ModifiedDate (ModifiedDate);  
GO  

次の例では、インデックスと制約が指定された複数の列を追加します。

ALTER TABLE Sales.SalesOrderDetail_inmem  
       ADD    CustomerID int NOT NULL DEFAULT -1 WITH VALUES,  
              ShipMethodID int NOT NULL DEFAULT -1 WITH VALUES,  
              INDEX ix_Customer (CustomerID);  
GO  

参照

メモリ最適化テーブル