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

適用対象: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 INDEXPAD_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  

参照

メモリ最適化テーブル