SQL Server 2016 新機能 Temporal Tables ( テンポラル テーブル ) について – パート3 –

Microsoft Japan Data Platform Tech Sales Team

中川

前々回前回の投稿では、SQL Server 2016 新機能の一つである Temporal Tables の概要や、設計時や開発時、運用時に知っておいていただきたいポイントをお伝えしました。今回は Temporal Tables をメモリ最適化テーブルと組み合わせた際の動作などについてご紹介いたします。

なお、メモリ最適化テーブル自体については本投稿では詳しく触れませんが、DB Onlineに記事(※1)を載せておりますのでそちらをご参照ください。

※1 「今さら聞けないSQL Serverのメモリ最適化テクノロジーと、押さえておきたいSQL Serverのデータベースセキュリティ」連載一覧

 

それでは早速、メモリ最適化テーブルと Temporal Tables との組み合わせについて見ていきたいと思います。

先ずは前々回、前回同様に以下のような構造を持ったテーブルを作成します。今回はインメモリ最適化テーブルのため、 with オプション部分が前回と違っています。なお、Temporal Tables を有効化できるのは持続性のあるメモリ最適化テーブル (DURABILITY = SCHEMA_AND_DATA) だけです。

 CREATE TABLE [dbo].[products]( [商品コード] [int] NOT NULL, [商品名] [nvarchar](40) COLLATE Japanese_CI_AS NOT NULL, [sysstart] [datetime2](7) GENERATED ALWAYS AS ROW START NOT NULL, [sysend] [datetime2](7) GENERATED ALWAYS AS ROW END NOT NULL, PERIOD FOR SYSTEM_TIME ([sysstart], [sysend]), CONSTRAINT [products_主キー] PRIMARY KEY NONCLUSTERED HASH   (   [商品コード]   ) WITH ( BUCKET_COUNT = 64)) WITH ( MEMORY_OPTIMIZED = ON , DURABILITY = SCHEMA_AND_DATA );GO

次に Temporal Tables を有効化します。

 ALTER TABLE Products   SET ( SYSTEM_VERSIONING = ON   ( HISTORY_TABLE = dbo.ProductsHistory ) )

ディスクベースの表にて Temporal Tables を有効化した場合と比較し、SSMSで見た限りでは違いは見られません。

image

ただ以下クエリを実行すると、実は内部オブジェクトが一つ追加されていることが確認できます。

 SELECT SCHEMA_NAME (T1.schema_id) as TemporalTableSchema     , OBJECT_NAME(IT.parent_object_id) as TemporalTableName     , T1.object_id as TemporalTableObjectId     , IT.Name as InternalHistoryStagingName      , SCHEMA_NAME (T2.schema_id) as HistoryTableSchema     , OBJECT_NAME (T1.history_table_id) as HistoryTableName   FROM sys.internal_tables IT    JOIN sys.tables T1      ON IT.parent_object_id = T1.object_id   JOIN sys.tables T2      ON T1.history_table_id = T2.object_id   WHERE T1.is_memory_optimized  = 1 AND T1.temporal_type = 2;GO

image

 

Temporal Tables を有効化した表と履歴テーブルへの履歴データの退避は同一トランザクション内で行う必要があります。ただ、インメモリ最適化テーブルはメモリ常住型のテーブルとなっており、その性能を活かすために履歴テーブルまでメモリに常駐し続けてはメモリを圧迫することになります。かといって、せっかくオンライン処理を高速化するためにインメモリ最適化テーブルを採用しているにも関わらず履歴テーブルがディスクベースですと、インメモリOLTP エンジンの性能メリットを 100% 活かせません。そのため、オンライン処理は履歴管理も含めてメモリ常駐型のテーブルで高速な処理を実現し、溜まった履歴データについてはディスク側にフラッシュさせる以下のようなアーキテクチャにより実用性を上げています。

image

 

上記クエリにて確認した追加内部オブジェクトは ➁ のインメモリタイプの履歴テーブルのことです。これは ➀ のインメモリ最適化テーブルにDMLが実行された際に、一時的に履歴データを格納するためのインメモリタイプの表(ステージングのような役割)となりますが、➀ が使用するメモリサイズの 8% に ➁ が達した場合、あるいは ”sp_xtp_flush_temporal_history” を実行された際に、➁ に溜まった履歴データを ③ にフラッシュさせてメモリ空間を解放します。これにより、インメモリOLTPエンジンの性能特性を活かしつつ、メモリ圧迫を最小限に抑えることが可能となっています。

 

全三回に分けて Temporal Talbes についてご紹介させていただきましたが如何でしたでしょうか。データが更新された際の履歴データの管理をこれまでは独自で実装されていたかと思いますが、それをデータベース側で実装し自動化してくれるのが Temporal Tables という機能ですので、是非ご利用いただければと思います。

 

関連記事