基本となるドキュメントは、インメモリの使用 (プレビュー) となりますが、SQL Database でのインメモリ OLTP が使用できるようになっています。
まだ触っていなかったので、ザクッと使ってみたいと思います。
■使用する際に気を付けておきたいこと
インメモリ OLTP はすべてのサービス層で使用できる機能ではありません。
ストアインデックスと同様に、「Premium」でのみ使用することができます。
また、データベースが 1 台の場合の Azure SQL Database のパフォーマンス ガイダンス に記載されていますが、現状は Elastic Database Pool には対応しておらず、シングルデータベースモデルでのみ使用することができます。
NOTE:
メモリ内 OLTP プレビューは現在のところ、単一データベースでのみサポートされており、エラスティック データベース プールのデータベースではサポートされていません。
また、Premium の中でも、パフォーマンスレベルに応じて、インメモリ OLTP で使用できるストレージのサイズが異なってきます。
# 投稿を書いている時点では、インメモリ OLTP の上限については、英語版のみ記載されているようでした。
また、プレビューの考慮事項 に記載されていますが、以下のような注意点があります。
インメモリ OLTP は、Premium Edition データベースでのみサポートされています。
インメモリ OLTP は、新規作成されたデータベースでのみサポートされます。コピーまたは復元の機能を使用して既存のデータベースを基に作成されたデータベースではサポートされません。ただし、新しいデータベースを作成した後は、インメモリ OLTP のすべての機能を維持しながらこのデータベースをコピーまたは復元できます。
特定のデータベースでインメモリ OLTP がサポートされているかどうかを確認するには、次のクエリを実行します。
インメモリ OLTP については、既存のデータベースを Premium に変更した際には使用できず、プレビューの実装が行われてから作成されたデータベースを Premium で使用する際に有効になっている機能となるようです。
そのため、既存のデータベースでインメモリ OLTP を使用したい場合は、手順 1. 新しい Premium データベースに実際のデータをコピーする に記載されているように、 bacpac で新規のデータベースに移行するというような考慮が必要となるようですので、この点は注意しておきたいですね。
Premium で使用できる状態であれば、以下のクエリの実行結果が「1」となります
SELECT DATABASEPROPERTYEX(DB_NAME(), 'IsXTPSupported');
■メモリ最適化テーブルを作ってみる
今回は新規に作成したデータベース (Basic で新規に作って Premium に変更したもの) を使用しており、インメモリ OLTP をサポートしていますので、メモリ最適化テーブルを作ってみたいと思います。
SQL Database のインメモリ? OLTP は、「SCHEMA_ONLY」「SCHEMA_AND_DATA」の両方を使用することができそうですので、永続化/非永続化のメモリ最適化テーブルを作ることができるようです。
どのタイミングでサーバーがフェールオーバーするかが見えないので、非永続化テーブルは使い勝手が難しそうですが。
今回は、TPC-H の ORDERS テーブルを作ってみたいと思います。
CREATE TABLE [dbo].[ORDERS]( [O_ORDERKEY] [int] NOT NULL PRIMARY KEY NONCLUSTERED , [O_CUSTKEY] [int] NOT NULL, [O_ORDERSTATUS] [nchar](1) NOT NULL, [O_TOTALPRICE] [decimal](15, 2) NOT NULL, [O_ORDERDATE] [date] NOT NULL, [O_ORDERPRIORITY] [nchar](15) NOT NULL, [O_CLERK] [nchar](15) NOT NULL, [O_SHIPPRIORITY] [int] NOT NULL, [O_COMMENT] [nvarchar](79) NOT NULL ) WITH (MEMORY_OPTIMIZED = ON, DURABILITY = SCHEMA_ONLY)
メモリ最適化テーブルで使用できるサイズについては、パフォーマンスレベルのインメモリ OLTP ストレージの上限に依存する形となりますが、これはどちらの永続化モード(「SCHEMA_ONLY」「SCHEMA_AND_DATA」)を使用していても、利用されることになります。
# 非永続化にしたからといって、ストレージ領域が消費されないということはありません。
BOX の SQL Server では、メモリ最適化テーブルを使用する場合は、ファイルグループの追加が必要でした。
SQL Database の場合は、メモリ最適化テーブル用のファイルグループについては、デフォルトで追加されている状態ですので、ファイルグループの作成は不要で、メモリ最適化テーブルを使用することができます。
select * from sys.database_files
また、インメモリ OLTP の実装によって、「sys.dm_db_resource_stats」に「xtp_storage_percent」という列が新たに追加されています。
この DMV の情報を使用することで、上限に対して、どの程度利用しているかを確認することができます。
情報を見ている限り、インメモリ OLTP では、
- avg_memory_usage_percent
- xtp_storage_percent
の両方が使用されているように見えますので、インメモリ OLTP 用のストレージと、物理メモリの両方が使用されていると考えていた方がよさそうです。
# memory_usage_percent の内数として xtp_storage_percent がある感じでしょうか。
■SQL Database のインメモリ OLTP の実装
SQL Database v12 のインメモリ OLTP の実装ですが、基本的には SQL Server 2016 の実装と同様となっているようです。
そのため、以下のような操作もサポートされています。
- メモリ最適化テーブル/ネイティブコンパイルストアドプロシージャに対しての ALTER の実行
- ネイティブコンパイルストアドプロシージャ内でのユーザー定義関数の呼び出し
- メモリ最適化テーブルの照合順序の緩和
- ネイティブコンパイルストアドプロシージャの JOIN の制限の緩和
- メモリ最適化テーブルと列ストアインデックスの組み合わせ (Operational Analytics の 1 シナリオ)
1 点気を付けておきたい内容としては、投稿を書いている時点の SQL Database では、データベースの互換性レベルが「120」がデフォルトの設定となっていることです。
これについては、Compatibility level 130 for Azure SQL Database V12 の内容となります。
互換性レベルが 120 でも上記に記載した、SQL Server 2016 相当の機能は使用することができるのですが、互換性レベル 130 で追加になった動作については利用することができません。
具体的には、ALTER DATABASE Compatibility Level (Transact-SQL) に書かれている動作となります。
現状の、SQL Database では P2 以上であれば、複数コアを使用することができるため、並列クエリの実行が可能となっています。
メモリ最適化テーブルで複数スレッドを使用した並列クエリを実行するためには、互換性レベルが「130」の必要があります。
下の画像は、互換性レベル「120」「130」で同一のクエリを実行した際の実行プランの違いになります。
互換性レベル「130」を使用することで、並列クエリが実行されているのが確認できますね。
列ストアインデックスを使用した際の、単一スレッドでのバッチモードについても動作が変わってきますので、P1 を使用している場合などはこの辺も意識しておいた方がよいかと。
SQL Database のメモリ最適化テーブルは、使用できるストレージサイズが明示的に決められていますが、使い方自体は、SQL Server 2016 の情報を追っておけばよさそうですね。
[…] SQL Database のインメモリ OLTP を使ってみる […]
Azure Update (2015.11.18) | ブチザッキ
18 11月 15 at 10:27