Memory Optimized Table にはいくつかの制限があります。
今回はその制限について少しまとめてみたいと思います。
BOL には SQL Server Support for In-Memory OLTP にまとめられています。
以前の投稿でも紹介したのですが、テーブルのデータ型には Supported Data Types に書かれているように制限があります。なお、行のサイズは最大で 8,060 バイトに制限がされています。
# BLOB は使用することができません。
テーブルの制限については Transact-SQL Support for In-Memory OLTP にも記載されています。
IDENTITY / ユニーク制約 / チェック制約 / 参照整合性制約はサポートされていないため、この辺は気を付ける必要が出てくるかと。
なお、プライマリキー制約は使えるのでレコードの一意性を担保することはできます。IDENTITY の代りには シーケンス を使用することになります。
一番重要となってくるのは Memory Optimized Table は作成するとテーブルの定義をインデックスの追加も含めて変更することができないという点になってきます。
テーブルの定義を変更したい場合には一度テーブルのデータを退避してテーブルを削除し、再作成してデータを再ロードする必要があります。
Memory Optimized Table を使用する場合にはこの制限を許容することができるかをまず検討する必要があります。
クエリ実行時にはデータベースを跨ぐクエリの利用は注意をする必要があります。
Supported SQL Server Features / Accessing Memory-Optimized Tables Using Interpreted Transact-SQL に記載されていますが、他のユーザーデータベースと JOIN をすることができません。
master に対しては JOIN をすることができますが、
ユーザーデータベースに対しては JOIN をすることができません。
tempdb に作成された一時テーブルとは JOIN をすることができますのでこの辺りを使うとよいのかもしれないですね。
また、使用できるテーブルはT-SQL とネイティブコンパイルされたストアドプロシージャでも制限は異なってきます。
ネイティブコンパイルされたストアドプロシージャは Memory Optimized Table にしかアクセスができないようなのでここも注意する必要があります。
また、ネイティブコンパイルされたストアドプロシージャでは SELECT * というような全列を対象としたクエリ実行ができませんのでこの辺も注意しておいたほうがよいかと思います。
簡略な表にまとめると以下のようになるでしょうか。
T-SQL / ストアドプロシージャ によるアクセス |
ネイティブコンパイルされた ストアドプロシージャによるアクセス |
|
メモリ最適化テーブルへのアクセス | 可能 | 可能 |
メモリ最適化テーブルと通常の テーブルの結合 |
可能 # WITH (SNAPSHOT) |
不可 |
メモリ最適化テーブル同士の結合 | 可能 | 可能 # OUTER JOIN がサポートされない |
メモリ最適化テーブルと他ユーザー データベースの結合 |
不可 | 不可 |
メモリ最適化テーブルとシステムデータベースの結合 | 可能 # WITH (SNAPSHOT) |
不可 |
メモリ最適化テーブルと一時テーブルの結合 | 可能 # WITH (SNAPSHOT) |
不可 # CREATE TABLE が実行できない # テーブル変数 / グローバル一時テーブルも不可 |
Transactions in Memory-Optimized Tables に書かれているトランザクション分離レベルにも注意をする必要があります。
Memory Optimized Table では、SQL Server のデフォルトの分離レベルである READ COMMITTED を明示的なトランザクションを設定した場合に使用することができません。
# 自動コミットの場合は使用できるようですが。
SQL Server 2014 では SNAPSHOT というヒントが追加されていますので、これを使用することでエラーが発生せずにクエリを実行することができます。
トランザクション分離レベルについては Guidelines for Transaction Isolation Levels with Memory-Optimized Tables / Transaction Isolation Levels に記載されていますのでこの辺の制限はきちんと理解しておく必要がありそうです。
また、Memory Optimized Table はロック / ラッチフリーモデルによる楽観的排他制御で実装されています。
そのため、複数のトランザクションから同じタイミングで同一のデータの更新が行われた場合には競合が発生し、後から更新したものはエラーとなります。
トランザクションのリトライについては Guidelines for Retry Logic for Transactions on Memory-Optimized Tables に記載されていますのでこの辺を参考にするとよいかと。
Memory Optimized Table では Native Complie したストアドプロシージャ以外も使用することができますが、いろいろと制約がありますので適用をする際には制限を理解しておく必要があります。
いちからはじめる Memory Optimized Table その 1
いちからはじめる Memory Optimized Table その 2
いちからはじめる Memory Optimized Table その 3
いちからはじめる Memory Optimized Table その 4
いちからはじめる Memory Optimized Table その 5
いちからはじめる Memory Optimized Table その 6
いちからはじめる Memory Optimized Table その 7 ←今回の投稿