実証: インメモリ OLTP によるパフォーマンスの向上

適用対象: SQL Server Azure SQL Database Azure SQL Managed Instance

このトピック内のコード サンプルは、メモリ最適化テーブルの高速なパフォーマンスを実証します。 パフォーマンス向上は、従来の解釈された Transact-SQL から、メモリ最適化テーブル内のデータにアクセスする場合にも明白になります。 このパフォーマンス向上は、ネイティブ コンパイル ストアド プロシージャ (NCSProc) からメモリ最適化テーブル内のデータにアクセスするときにさらに大きくなります。

インメモリ OLTP のパフォーマンスを改善できる可能性を示す包括的なデモについては、 In-Memory OLTP Performance Demo v1.0を参照してください。

この記事のサンプル コードはシングル スレッドで、インメモリ OLTP のコンカレンシーの利点を利用していません。 コンカレンシーを使用するワークロードでは、さらにパフォーマンスが向上します。 このサンプル コードでは、パフォーマンス向上の一面のみ、具体的には INSERT のデータ アクセスの効率性を示します。

メモリ最適化テーブルによって達成されるパフォーマンス向上は、NCSProc から、メモリ最適化テーブル内のデータにアクセスするときに完全に実現します。

コード例

次のサブセクションでは、各手順について説明します。

手順 1a: SQL Server を使用する場合の前提条件

この最初のサブセクションの手順は、SQL Server で実行している場合にのみ適用され、Azure SQL データベース で実行している場合には適用されません。 次の操作を行います。

  1. SQL Server Management Studio (SSMS.exe) を使用して、SQL Server に接続します。 または、SSMS.exe に類似した任意のツールも使用できます。

  2. C:\data\ という名前のディレクトリを手動で作成します。 サンプルの Transact-SQL コードでは、ディレクトリがあらかじめ存在することが想定されています。

  3. 短い T-SQL を実行して、データベースおよびそのメモリ最適化ファイル グループを作成します。

go  
CREATE DATABASE imoltp;    --  Transact-SQL  
go  
  
ALTER DATABASE imoltp ADD FILEGROUP [imoltp_mod]  
    CONTAINS MEMORY_OPTIMIZED_DATA;  
  
ALTER DATABASE imoltp ADD FILE  
    (name = [imoltp_dir], filename= 'c:\data\imoltp_dir')  
    TO FILEGROUP imoltp_mod;  
go  
  
USE imoltp;  
go  

手順 1b: Azure SQL データベース を使用する場合の前提条件

このサブセクションは、Azure SQL データベースを使用している場合にのみ適用されます。 次の操作を行います。

  1. コード例に使用する既存のテスト データベースを決定します。

  2. 新しいテスト データベースを作成する場合は、 Azure ポータル を使用して、 imoltpという名前のデータベースを作成します。

その場合に Azure ポータルを使用する手順については、「 Get Started with Azure SQL Database (Azure SQL Database の概要)」を参照してください。

手順 2: メモリ最適化テーブルと NCSProc を作成する

この手順では、メモリ最適化テーブルとネイティブ コンパイル ストアド プロシージャ (NCSProc) を作成します。 次の操作を行います。

  1. SSMS.exe を使用して、新しいデータベースに接続します。

  2. データベースで、次の T-SQL を実行します。

go  
DROP PROCEDURE IF EXISTS ncsp;  
DROP TABLE IF EXISTS sql;  
DROP TABLE IF EXISTS hash_i;  
DROP TABLE IF EXISTS hash_c;  
go  
  
CREATE TABLE [dbo].[sql] (  
  c1 INT NOT NULL PRIMARY KEY,  
  c2 NCHAR(48) NOT NULL  
);  
go  
  
CREATE TABLE [dbo].[hash_i] (  
  c1 INT NOT NULL PRIMARY KEY NONCLUSTERED HASH WITH (BUCKET_COUNT=1000000),  
  c2 NCHAR(48) NOT NULL  
) WITH (MEMORY_OPTIMIZED=ON, DURABILITY = SCHEMA_AND_DATA);  
go  
  
CREATE TABLE [dbo].[hash_c] (  
  c1 INT NOT NULL PRIMARY KEY NONCLUSTERED HASH WITH (BUCKET_COUNT=1000000),  
  c2 NCHAR(48) NOT NULL  
) WITH (MEMORY_OPTIMIZED=ON, DURABILITY = SCHEMA_AND_DATA);  
go  
  
CREATE PROCEDURE ncsp  
    @rowcount INT,  
    @c NCHAR(48)  
  WITH NATIVE_COMPILATION, SCHEMABINDING, EXECUTE AS OWNER  
  AS   
  BEGIN ATOMIC   
  WITH (TRANSACTION ISOLATION LEVEL = SNAPSHOT, LANGUAGE = N'us_english')  
  DECLARE @i INT = 1;  
  WHILE @i <= @rowcount  
  BEGIN;  
    INSERT INTO [dbo].[hash_c] VALUES (@i, @c);  
    SET @i += 1;  
  END;  
END;  
go  

手順 3: コードを実行する

ここで、メモリ最適化テーブルによるパフォーマンスを実証するクエリを実行できます。 次の操作を行います。

  1. SSMS.exe を使用して、データベースで次の T-SQL を実行します。

    この最初の実行で生成される速度などのパフォーマンス データをすべて無視します。 最初の実行では、メモリの初期割り当てなど、1 回限りの操作が実行されることを確認します。

  2. もう一度 SSMS.exe を使用して、データベースで次の T-SQL を再実行します。

go  
SET STATISTICS TIME OFF;  
SET NOCOUNT ON;  
  
-- Inserts, one at a time.  
  
DECLARE @starttime DATETIME2 = sysdatetime();  
DECLARE @timems INT;  
DECLARE @i INT = 1;  
DECLARE @rowcount INT = 100000;  
DECLARE @c NCHAR(48) = N'12345678901234567890123456789012345678';  
  
-- Harddrive-based table and interpreted Transact-SQL.  
  
BEGIN TRAN;  
  WHILE @i <= @rowcount  
  BEGIN;  
    INSERT INTO [dbo].[sql] VALUES (@i, @c);  
    SET @i += 1;  
  END;  
COMMIT;  
  
SET @timems = datediff(ms, @starttime, sysdatetime());  
SELECT 'A: Disk-based table and interpreted Transact-SQL: '  
    + cast(@timems AS VARCHAR(10)) + ' ms';  
  
-- Interop Hash.  
  
SET @i = 1;  
SET @starttime = sysdatetime();  
  
BEGIN TRAN;  
  WHILE @i <= @rowcount  
    BEGIN;  
      INSERT INTO [dbo].[hash_i] VALUES (@i, @c);  
      SET @i += 1;  
    END;  
COMMIT;  
  
SET @timems = datediff(ms, @starttime, sysdatetime());  
SELECT 'B: memory-optimized table with hash index and interpreted Transact-SQL: '  
    + cast(@timems as VARCHAR(10)) + ' ms';  
  
-- Compiled Hash.  
  
SET @starttime = sysdatetime();  
  
EXECUTE ncsp @rowcount, @c;  
  
SET @timems = datediff(ms, @starttime, sysdatetime());  
SELECT 'C: memory-optimized table with hash index and native SP:'  
    + cast(@timems as varchar(10)) + ' ms';  
go  
  
DELETE sql;  
DELETE hash_i;  
DELETE hash_c;  
go  

次に、2 回目のテスト実行で生成される出力時間の統計を示します。

10453 ms , A: Disk-based table and interpreted Transact-SQL.  
5626 ms , B: memory-optimized table with hash index and interpreted Transact-SQL.  
3937 ms , C: memory-optimized table with hash index and native SP.  

参照

インメモリ OLTP (インメモリ最適化)