メモリ最適化テーブルの概要Introduction to Memory-Optimized Tables

適用対象: yesSQL Server yesAzure SQL Database noAzure Synapse Analytics (SQL DW) noParallel Data Warehouse APPLIES TO: yesSQL Server yesAzure SQL Database noAzure Synapse Analytics (SQL DW) noParallel Data Warehouse

メモリ最適化テーブルは、CREATE TABLE (Transact-SQL) を使用して作成されます。Memory-optimized tables are created using CREATE TABLE (Transact-SQL).

メモリ最適化テーブルは既定では完全に持続性があり、従来のディスクベース テーブルのトランザクションと同様に、メモリ最適化テーブルのトランザクションは完全に原子性、一貫性、分離性、持続性 (ACID) を備えています。Memory-optimized tables are fully durable by default, and, like transactions on (traditional) disk-based tables, transactions on memory-optimized tables are fully atomic, consistent, isolated, and durable (ACID). メモリ最適化テーブルおよびネイティブ コンパイル ストアド プロシージャは、Transact-SQLTransact-SQL 機能のサブセットのみをサポートします。Memory-optimized tables and natively compiled stored procedures support only a subset of Transact-SQLTransact-SQL features.

SQL Server 2016 以降、および Azure SQL Database では、インメモリ OLTP に固有の 照合順序またはコード ページ に関する制限はありません。Starting with SQL Server 2016, and in Azure SQL Database, there are no limitations for collations or code pages that are specific to In-Memory OLTP.

メモリ最適化テーブルのプライマリ ストレージは、メイン メモリです。The primary storage for memory-optimized tables is the main memory. テーブルの行は、メモリから読み込まれ、メモリに書き込まれます。Rows in the table are read from and written to memory. ディスク上にはテーブル データの 2 番目のコピーが保持されますが、持続性を実現するためのものにすぎません。A second copy of the table data is maintained on disk, but only for durability purposes. 持続性のあるテーブルの詳細については、「 メモリ最適化オブジェクト用ストレージの作成と管理 」を参照してください。See Creating and Managing Storage for Memory-Optimized Objects for more information about durable tables. データベース復旧中は、メモリ最適化テーブルのデータはディスクからの読み取りのみ行われます (たとえば、Data in memory-optimized tables is only read from disk during database recovery (eg. サーバー再起動後などの場合)。after a server restart).

パフォーマンスをさらに向上するために、インメモリ OLTP ではトランザクションの持続性が遅延している状態の持続性テーブルがサポートされます。For even greater performance gains, In-Memory OLTP supports durable tables with transaction durability delayed. 遅延持続性トランザクションは、トランザクションがコミットし、クライアントに制御を返した後すぐにディスクに保存されます。Delayed durable transactions are saved to disk soon after the transaction has committed and control was returned to the client. ディスクに保存せずにコミットされたトランザクションは、パフォーマンスの向上と引き換えに、サーバー クラッシュまたはフェールオーバー時に失われます。In exchange for the increased performance, committed transactions that have not saved to disk are lost in a server crash or fail over.

既定の持続性を持つメモリ最適化テーブルだけでなく、 SQL ServerSQL Server は、記録やディスクへのデータ保存が行われない持続性のないメモリ最適化テーブルをサポートします。Besides the default durable memory-optimized tables, SQL ServerSQL Server also supports non-durable memory-optimized tables, which are not logged and their data is not persisted on disk. つまり、これらのテーブルのトランザクションはディスク IO を必要としませんが、サーバーのクラッシュまたはフェールオーバーが発生した場合、データを復旧できません。This means that transactions on these tables do not require any disk IO, but the data will not be recovered if there is a server crash or failover.

インメモリ OLTP は、開発、配置、管理、サポートなど、すべての領域においてシームレスな使用環境を提供するために、 SQL ServerSQL Server と統合されています。In-Memory OLTP is integrated with SQL ServerSQL Server to provide a seamless experience in all areas such as development, deployment, manageability, and supportability. データベースには、ディスク ベースのオブジェクトと同様にインメモリのオブジェクトを含めることができます。A database can contain in-memory as well as disk-based objects.

メモリ最適化テーブル内の行には、バージョンが付いています。Rows in memory-optimized tables are versioned. これは、テーブルの各行に複数のバージョンが存在する可能性があることを意味します。This means that each row in the table potentially has multiple versions. 行バージョンはいずれも、同じテーブル データ構造で保持されます。All row versions are maintained in the same table data structure. 行のバージョン管理は、同じ行に対して読み取りと書き込みを同時に実行できるようにするために使用します。Row versioning is used to allow concurrent reads and writes on the same row. 同じ行に対して読み取りおよび書き込みを同時に実行する方法の詳細については、「 Transactions with Memory-Optimized Tables (メモリ最適化テーブルでのトランザクション)」を参照してください。For more information about concurrent reads and writes on the same row, see Transactions with Memory-Optimized Tables.

次の図は、複数バージョン管理について説明したものです。The following figure illustrates multi-versioning. この図では、行が 3 つあるテーブルを示しています。行のそれぞれに、バージョンが複数存在します。The figure shows a table with three rows and each row has different versions.

複数バージョン管理。Multi-versioning.

テーブルには、r1、r2、および r3 の 3 行があります。The table has three rows: r1, r2, and r3. r1 には 3 つ、r2 には 2 つ、r3 には 4 つのバージョンがあります。r1 has three versions, r2 has two versions, and r3 has four versions. 同じ行に複数のバージョンがある場合にも、メモリ上の場所が連続しているとは限らないことに注意してください。Note that different versions of the same row do not necessarily occupy consecutive memory locations. バージョンの異なる行がテーブル データ構造のさまざまな場所に分散して配置されていることもあります。The different row versions can be dispersed throughout the table data structure.

メモリ最適化テーブルのデータ構造は、行バージョンのコレクションと考えることができます。The memory-optimized table data structure can be seen as a collection of row versions. ディスク ベース テーブルの行がページとエクステントによって整理され、個々の行がページ番号とページ オフセットでアドレス指定されているのに対して、メモリ最適化テーブルの行バージョンは、8 バイトのメモリ ポインターを使用してアドレスが指定されています。Rows in disk-based tables are organized in pages and extents, and individual rows addressed using page number and page offset, row versions in memory-optimized tables are addressed using 8-byte memory pointers.

メモリ最適化テーブルのデータには、次の 2 つの方法でアクセスできます。Data in memory-optimized tables is accessed in two ways:

  • ネイティブ コンパイル ストアド プロシージャを経由してアクセスできます。Through natively compiled stored procedures.

  • ネイティブ コンパイル ストアド プロシージャの外で、解釈された Transact-SQLTransact-SQLを経由してアクセスできます。Through interpreted Transact-SQLTransact-SQL, outside of a natively-compiled stored procedure. これらの Transact-SQLTransact-SQL ステートメントは、解釈されたストアド プロシージャ内にあっても、アドホック Transact-SQLTransact-SQL ステートメントであってもかまいません。These Transact-SQLTransact-SQL statements may be either inside interpreted stored procedures or they may be ad-hoc Transact-SQLTransact-SQL statements.

メモリ最適化テーブルのデータへのアクセスAccessing Data in Memory-Optimized Tables

メモリ最適化テーブルには、ネイティブ コンパイル ストアド プロシージャ (「ネイティブ コンパイル ストアド プロシージャ」) からアクセスするのが最も効率的です。Memory-optimized tables can be accessed most efficiently from natively compiled stored procedures (Natively Compiled Stored Procedures). メモリ最適化テーブルのデータには、(従来の) 解釈された Transact-SQLTransact-SQLでもアクセスできます。Memory-optimized tables can also be accessed with (traditional) interpreted Transact-SQLTransact-SQL. 解釈された Transact-SQLTransact-SQL とは、ネイティブ コンパイル ストアド プロシージャを使用せずにメモリ最適化テーブルにアクセスすることを表します。Interpreted Transact-SQLTransact-SQL refers to accessing memory-optimized tables without a natively compiled stored procedure. 解釈された Transact-SQLTransact-SQL アクセスの例として、DML トリガー、アドホック Transact-SQLTransact-SQL バッチ、ビュー、およびテーブル値関数からのメモリ最適化テーブルへのアクセスがあります。Some examples of interpreted Transact-SQLTransact-SQL access include accessing a memory-optimized table from a DML trigger, ad hoc Transact-SQLTransact-SQL batch, view, and table-valued function.

次の表に、さまざまなオブジェクトへのネイティブ アクセスおよび解釈された Transact-SQLTransact-SQL アクセスを示します。The following table summarizes native and interpreted Transact-SQLTransact-SQL access for various objects.

機能Feature ネイティブ コンパイル ストアド プロシージャを使用したアクセスAccess Using a Natively Compiled Stored Procedure 解釈された Transact-SQLTransact-SQL アクセスInterpreted Transact-SQLTransact-SQL Access CLR アクセスCLR Access
メモリ最適化テーブルMemory-optimized table はいYes はいYes なし*No*
メモリ最適化テーブル型Memory-optimized table type はいYes はいYes いいえNo
ネイティブ コンパイル ストアド プロシージャNatively compiled stored procedure ネイティブ コンパイル ストアド プロシージャの入れ子がサポートされるようになりました。Nesting of natively compiled stored procedures is now supported. 参照先のプロシージャがネイティブにコンパイルされている場合は、ストアド プロシージャ内で EXECUTE 構文を使用できます。You can use the EXECUTE syntax inside the stored procedures, as long as the referenced procedure is also natively compiled. はいYes いいえ*No*

*コンテキスト接続 (CLR モジュールを実行するときの SQL ServerSQL Server からの接続) からメモリ最適化テーブルまたはネイティブ コンパイル ストアド プロシージャにアクセスすることはできません。*You cannot access a memory-optimized table or natively compiled stored procedure from the context connection (the connection from SQL ServerSQL Server when executing a CLR module). ただし、別の接続を作成して開き、そこからメモリ最適化テーブルおよびネイティブ コンパイル ストアド プロシージャにアクセスできます。You can, however, create and open another connection from which you can access memory-optimized tables and natively compiled stored procedures.

パフォーマンスとスケーラビリティPerformance and Scalability

インメモリ OLTP を使用することで実現できるパフォーマンスの向上には、次の要素が影響します。The following factors will affect the performance gains that can be achieved with In-Memory OLTP:

通信: 短いストアド プロシージャに対する多数の呼び出しを実行するアプリケーションは、各ストアド プロシージャにより多くの機能が実装されて呼び出しが少なくて済むアプリケーションと比較した場合、パフォーマンス向上の点で劣る場合があります。Communication: An application with many calls to short stored procedures may see a smaller performance gain compared to an application with fewer calls and more functionality implemented in each stored procedure.

Transact-SQLTransact-SQL 実行: インメモリ OLTP は、解釈されたストアド プロシージャやクエリ実行ではなく、ネイティブ コンパイル ストアド プロシージャを使用する場合に、最高のパフォーマンスを発揮します。Transact-SQLTransact-SQL Execution: In-Memory OLTP achieves the best performance when using natively compiled stored procedures rather than interpreted stored procedures or query execution. こうしたストアド プロシージャからメモリ最適化テーブルにアクセスすると有利な場合があります。There can be a benefit to accessing memory-optimized tables from such stored procedures.

範囲スキャンとポイント参照: メモリ最適化された非クラスター化インデックスでは、範囲スキャンと並べ替えられたスキャンがサポートされています。Range Scan vs Point Lookup: Memory-optimized nonclustered indexes support range scans and ordered scans. ポイント参照については、メモリ最適化された非クラスター化インデックスよりもメモリ最適化されたハッシュ インデックスの方がパフォーマンスが優れています。For point lookups, memory-optimized hash indexes have better performance than memory-optimized nonclustered indexes. メモリ最適化された非クラスター化インデックスはディスク ベース インデックスよりもパフォーマンスが優れています。Memory-optimized nonclustered indexes have better performance than disk-based indexes.

  • SQL Server 2016 以降、メモリ最適化テーブルのクエリ プランでは並列でテーブルをスキャンできます。Starting in SQL Server 2016, the query plan for a memory-optimized table can scan the table in parallel. これにより、分析クエリのパフォーマンスが向上します。This improves the performance of analytical queries.
    • ハッシュ インデックスも、SQL Server 2016 で並列スキャン可能になりました。Hash indexes also became scannable in parallel in SQL Server 2016.
    • 非クラスター化インデックスも、SQL Server 2016 で並列スキャン可能になりました。Nonclustered indexes also became scannable in parallel in SQL Server 2016.
    • 列ストア インデックスは、SQL Server 2014 での採用時から並列スキャン可能です。Columnstore indexes have been scannable in parallel since their inception in SQL Server 2014.

インデックス操作: インデックス操作はログに記録されず、メモリ内にのみ存在します。Index operations: Index operations are not logged, and they exist only in memory.

同時実行: ラッチの競合やブロックなど、エンジンレベルのコンカレンシーがパフォーマンスに影響するアプリケーションの場合、アプリケーションをインメモリ OLTP に移行するとパフォーマンスが大幅に向上します。Concurrency: Applications whose performance is affected by engine-level concurrency, such as latch contention or blocking, improves significantly when the application moves to In-Memory OLTP.

次の表は、リレーショナル データベースで一般的に生じるパフォーマンスとスケーラビリティの問題、およびインメモリ OLTP によってどのようにパフォーマンスが向上するかを示しています。The following table lists the performance and scalability issues that are commonly found in relational databases and how In-Memory OLTP can improve performance.

問題点Issue インメモリ OLTP の影響In-Memory OLTP Impact
パフォーマンスPerformance

リソース (CPU、I/O、ネットワーク、またはメモリ) の使用率が高い。High resource (CPU, I/O, network or memory) usage.
CPUCPU
ネイティブ コンパイル ストアド プロシージャは、解釈されたストアド プロシージャに比較すると Transact-SQLTransact-SQL ステートメントを実行するために必要な命令数が少ないため、CPU の使用率を大幅に下げることができます。Natively compiled stored procedures can lower CPU usage significantly because they require significantly fewer instructions to execute a Transact-SQLTransact-SQL statement compared to interpreted stored procedures.

インメモリ OLTP では、1 台のサーバーで 5 ~ 10 台のサーバーのスループットに対応できる可能性があるため、スケールアウトしたワークロード環境でのハードウェア投資を削減できます。In-Memory OLTP can help reduce the hardware investment in scaled-out workloads because one server can potentially deliver the throughput of five to ten servers.

I/OI/O
データやインデックス ページに対する処理に起因する I/O のボトルネックが発生する場合、インメモリ OLTP ではボトルネックを低減できます。If you encounter an I/O bottleneck from processing to data or index pages, In-Memory OLTP may reduce the bottleneck. また、インメモリ OLTP オブジェクトのチェックポイント処理は連続的であり、I/O 操作の突然の増加を招くことはありません。Additionally, the checkpointing of In-Memory OLTP objects is continuous and does not lead to sudden increases in I/O operations. ただし、パフォーマンス クリティカルなテーブルのワーキング セットがメモリに収まらない場合、インメモリ OLTP では、データがメモリ常駐型であることが必要であるため、パフォーマンスは向上しません。However, if the working set of the performance critical tables does not fit in memory, In-Memory OLTP will not improve performance because it requires data to be memory resident. ログ記録で I/O のボトルネックが発生する場合、インメモリ OLTP はログ記録が少ないためボトルネックを軽減できます。If you encounter an I/O bottleneck in logging, In-Memory OLTP can reduce the bottleneck because it does less logging. 1 つ以上のメモリ最適化テーブルが持続性のないテーブルとして構成されている場合は、データのログ記録を無効にできます。If one or more memory-optimized tables are configured as non-durable tables, you can eliminate logging for data.

[メモリ]Memory
インメモリ OLTP では、パフォーマンス上の利点は得られません。In-Memory OLTP does not offer any performance benefit. インメモリ OLTP では、オブジェクトがメモリ常駐型であることが必要になるため、メモリの負荷が増加する可能性があります。In-Memory OLTP can put extra pressure on memory as the objects need to be memory resident.

ネットワークNetwork
インメモリ OLTP では、パフォーマンス上の利点は得られません。In-Memory OLTP does not offer any performance benefit. データは、データ層からアプリケーション層に渡す必要があります。The data needs to be communicated from data tier to application tier.
スケーラビリティScalability

SQL ServerSQL Server アプリケーションでのスケーリングの問題のほとんどは、ロック、ラッチ、スピンロックの競合など、同時実行の問題が原因です。Most scaling issues in SQL ServerSQL Server applications are caused by concurrency issues such as contention in locks, latches, and spinlocks.
ラッチの競合Latch Contention
一般的なシナリオとして、キー順に行を同時に挿入した場合の、インデックスの最終ページでの競合を挙げることができます。A typical scenario is contention on the last page of an index when inserting rows concurrently in key order. インメモリ OLTP では、データへのアクセス時にラッチを使用しないため、ラッチの競合に関連するスケーラビリティの問題は完全になくなります。Because In-Memory OLTP does not take latches when accessing data, the scalability issues related to latch contentions are fully removed.

スピンロックの競合Spinlock Contention
インメモリ OLTP では、データへのアクセス時にラッチを使用しないため、スピンロックの競合に関連するスケーラビリティの問題は完全になくなります。Because In-Memory OLTP does not take latches when accessing data, the scalability issues related to spinlock contentions are fully removed.

ロックに関連する競合Locking Related Contention
データベース アプリケーションで読み取り操作と書き込み操作の間にブロックの問題が発生した場合、インメモリ OLTP では、新しい形式のオプティミスティック コンカレンシーを使用してすべてのトランザクション分離レベルを実装するため、ブロックの問題は排除されます。If your database application encounters blocking issues between read and write operations, In-Memory OLTP removes the blocking issues because it uses a new form of optimistic concurrency control to implement all transaction isolation levels. インメモリ OLTP では行バージョンを格納するために TempDB は使用されません。In-Memory OLTP does not use TempDB to store row versions.

2 つの同時実行トランザクションで同じ行を更新しようとした場合など、2 つの書き込み操作間の競合によってスケーリングの問題が発生した場合、インメモリ OLTP では、一方のトランザクションが成功し、他方のトランザクションは失敗するようになります。If the scaling issue is caused by conflict between two write operations, such as two concurrent transactions trying to update the same row, In-Memory OLTP lets one transaction succeed and fails the other transaction. 失敗したトランザクションは明示的または暗黙的に再送信して、トランザクションを再試行する必要があります。The failed transaction must be re-submitted either explicitly or implicitly, re-trying the transaction. いずれの場合も、アプリケーションに変更を加える必要があります。In either case, you need to make changes to the application.

アプリケーションで 2 つの書き込み操作間の競合が頻繁に発生する場合、オプティミスティック ロックの価値は減少します。If your application experiences frequent conflicts between two write operations, the value of optimistic locking is diminished. このアプリケーションはインメモリ OLTP に適していません。The application is not suitable for In-Memory OLTP. ほとんどの OLTP アプリケーションでは、競合がロックのエスカレーションによって引き起こされない限り、書き込みの競合はありません。Most OLTP applications don't have a write conflicts unless the conflict is induced by lock escalation.

メモリ最適化テーブルの行レベルのセキュリティRow-Level Security in Memory-Optimized Tables

行レベルのセキュリティ はメモリ最適化テーブルでサポートされます。Row-Level Security is supported in memory-optimized tables. 行レベルのセキュリティ ポリシーは、基本的には、ディスク ベース テーブルと同じように、メモリ最適化テーブルに適用できますが、セキュリティ述語として使用されるインライン テーブル値関数をネイティブにコンパイル (WITH NATIVE_COMPILATION オプションを使用して作成) しなければならない場合を除きます。Applying Row-Level Security policies to memory-optimized tables is essentially the same as disk-based tables, except that the inline table-valued functions used as security predicates must be natively compiled (created using the WITH NATIVE_COMPILATION option). 詳細については、「 行レベルのセキュリティ 」トピックの「 Cross-Feature Compatibility (機能間の互換性) 」セクションを参照してください。For details, see the Cross-Feature Compatibility section in the Row-Level Security topic.

行レベルのセキュリティに不可欠なさまざまな組み込みのセキュリティ関数が、インメモリ テーブルに対して有効になっています。Various built-in security functions that are essential to row-level security have been enabled for in-memory tables. 詳細については、「 ネイティブ コンパイル モジュールの組み込み関数」を参照してください。For details, see Built-in Functions in Natively Compiled Modules.

EXECUTE AS CALLER - ヒントが指定されていなくても、すべてのネイティブ モジュールが EXECUTE AS CALLER を既定でサポートおよび使用しています。EXECUTE AS CALLER - All native modules now support and use EXECUTE AS CALLER by default, even if the hint is not specified. これは、すべての行レベルのセキュリティ述語関数が EXECUTE AS CALLER を使用するものと見なされ、その関数 (およびその内部で使用される組み込み関数) は、呼び出しユーザーのコンテキストで評価されるためです。This is because it is expected that all row-level security predicate functions will use EXECUTE AS CALLER so that the function (and any built-in functions used within it) will be evaluated in the context of the calling user.
EXECUTE AS CALLER には、呼び出し元のアクセス許可チェックによるパフォーマンス ヒットがそれほどありません (約 10%)。EXECUTE AS CALLER has a small (approximately10%) performance hit caused by permission checks on the caller. モジュールで EXECUTE AS OWNER または EXECUTE AS SELF が明示的に指定されている場合、これらのアクセス許可のチェックと関連するパフォーマンス コストは回避されますが、If the module specifies EXECUTE AS OWNER or EXECUTE AS SELF explicitly, these permission checks and their associated performance cost will be avoided. このオプションのいずれかを、上記の組み込み関数と共に使用すると、コンテキスト切り替えが必要になるため、パフォーマンス ヒットがかなり大きくなります。However, using either of these options together with the built-in functions above will incur a significantly higher performance hit due to the necessary context-switching.

シナリオScenarios

SQL Server インメモリ OLTPSQL Server In-Memory OLTP によってパフォーマンスを向上できる典型的なシナリオの概要については、「 インメモリ OLTP」を参照してください。For a brief discussion of typical scenarios where SQL Server インメモリ OLTPSQL Server In-Memory OLTP can improve performance, see In-Memory OLTP.

参照See Also

インメモリ OLTP (インメモリ最適化)In-Memory OLTP (In-Memory Optimization)