これは、SQLServerインメモリOLTPに関する一連の記事の2番目の記事です。
紹介記事— SQL ServerインメモリOLTPでは、新しいHekatonエンジンの基本を簡単に紹介しました。このパートでは、練習に焦点を当てます。具体的には、メモリ内で最適化されたデータベースとテーブルを作成する方法と、T-SQLを使用してそれらを評価する方法について説明します。
メモリ最適化データベースの使用を開始するための前提条件
インメモリOLTPは、SQL Server2014またはSQLServer2016の64ビットEnterpriseまたはDeveloperエディションとともに自動的にインストールされます。SQLServer32ビットエディションは、インメモリOLTPコンポーネントを提供しません。
したがって、SQLServerの64ビットDeveloperEditionがコンピューターにインストールされている場合は、追加のセットアップなしでメモリ最適化データを格納するデータベースとデータ構造の作成を開始できます。
メモリ最適化テーブルを含むすべてのデータベースには、1つのMEMORY_OPTIMIZED_DATAファイルグループが含まれている必要があります。このファイルグループには、1つまたは複数のコンテナが含まれています。すべてのコンテナには、データやデルタファイルが格納されます。 SQL Serverはこれらのファイルを使用して、メモリ最適化テーブルを回復します。コンテナは、
FILESTREAMファイルグループと同様に異なるディスクアレイに配置できます。
メモリ最適化ファイルグループを作成するための構文は、従来のFILESTREAMファイルグループの場合とほぼ同じですが、いくつかの違いがあります。
- データベース用に作成できるメモリ最適化ファイルグループは1つだけです。
- CONTAINSMEMORY_OPTIMIZED_DATAオプションは明示的に指定する必要があります。
データベースを作成する過程でファイルグループを作成できます:
CREATE DATABASE InMemoryDemo ON PRIMARY ( NAME = N'InMemoryDemo', FILENAME = N'D:\Data\InMemoryOLTPDemo.mdf' ), FILEGROUP IMOFG CONTAINS MEMORY_OPTIMIZED_DATA ( NAME = N'InMemoryDemo_Data', FILENAME = N'D:\IMOFG\InMemoryDemo_Data.mdf' )
または、MEMORY_OPTIMIZED_DATAファイルグループを既存のデータベースに追加してから、そのファイルグループにファイルを追加することもできます。
-- Adding the containers ALTER DATABASE DemoDB ADD FILE ( NAME = 'DemoDB_Mod', FILENAME = 'D:\Data\DemoDB_Mod' ) TO FILEGROUP DemoDB_Mod
内部的には、インメモリOLTPはFILESTREAMテクノロジーに基づくストリーミングメカニズムを使用しており、シーケンシャルI/Oアクセスに適しています。
メモリ最適化テーブルの作成
これで、メモリ最適化オブジェクトの作成を開始するために必要なものがすべて揃いました。メモリ最適化テーブルを作成しましょう。
メモリ内で最適化されたテーブルを作成するための構文は、ディスクベースのテーブルを作成するための構文と非常によく似ています。ただし、いくつかの拡張機能と制限があります。
- MEMORY_OPTIMIZED =ON句は、テーブルがメモリ内で最適化されていることを識別します。
- メモリ内で最適化されたテーブルは、従来のテーブルがサポートするすべてのデータ型をサポートしているわけではありません。次のデータ型はサポートされていません:
- datetimeoffset
- 地理
- ジオメトリ
- 階層化
- 行バージョン
- XML
- sql_variant
- ユーザー定義タイプ
メモリ最適化テーブルは、次の耐久性値を使用して作成できます:SCHEMA_AND_DATAまたはSCHEMA_ONLY。 SCHEMA_AND_DATAがデフォルト値です。
SCHEMA_ONLYを指定した場合、テーブルへのすべての変更はログに記録されず、テーブルデータはディスクに保存されません。
すべてのメモリ最適化テーブルには、少なくとも1つのインデックスが含まれている必要があります。 PRIMARY KEY制約は、暗黙的にインデックスを作成することに注意してください。耐久性のあるメモリ最適化テーブルには、常にPRIMARYKEY制約が必要です。
CREATE TABLE dbo.Person ( [Name] VARCHAR(32) NOT NULL PRIMARY KEY NONCLUSTERED ,[City] VARCHAR(32) NULL ,[Country] VARCHAR(32) NULL ,[State_Province] VARCHAR(32) NULL ,[LastModified] DATETIME NOT NULL ) WITH (MEMORY_OPTIMIZED = ON, DURABILITY = SCHEMA_AND_DATA);
すべての列が作成されたら、複合インデックスを追加できます:
CREATE TABLE dbo.Person ( [Name] VARCHAR(32) NOT NULL PRIMARY KEY NONCLUSTERED ,[City] VARCHAR(32) NULL ,[Country] VARCHAR(32) NULL ,[State_Province] VARCHAR(32) NULL ,[LastModified] DATETIME NOT NULL ,INDEX T1_INDX_C1C2 NONCLUSTERED ([Name], [City]) ) WITH (MEMORY_OPTIMIZED = ON, DURABILITY = SCHEMA_AND_DATA);
インメモリ最適化テーブルを作成すると、インメモリOLTPエンジンは、そのテーブルにアクセスできるようにDMLルーチンを作成します。ルーチンをDLLファイルとしてロードします。特定の操作について、SQLServerは必要なDLLファイルを呼び出します。
テーブルとインデックスの変更
SQL Server 2016より前ではテーブルを変更することはできませんでした。スキーマを変更するには、メモリ内のテーブルを削除して再作成する必要がありました。
SQL Serverの新しいリリースでは、ALTERTABLEが部分的にサポートされています。
SQL Server 2016には、列、インデックス、および制約の追加と削除(変更)などのオフライン操作を実行する機能があります。また、SSMSテーブルデザイナーまたはdbForge Studio forSQLServerテーブルエディターを使用してメモリ内テーブルを操作できるようになりました。
ALTERTABLEではテーブルを再構築する必要があることに注意してください。そのため、この操作を実行する前に、十分なメモリがあることを確認する必要があります。再構築操作中に、すべての行が新しいテーブルに再挿入され、ALTER操作の実行中はテーブルを使用できなくなります。
1つのテーブルに複数の変更を導入し、それらを1つのALTERTABLEステートメントに組み合わせることができます。列、インデックス、および制約を追加したり、列、インデックス、および制約を削除したりできます。 ADDコマンドとDROPコマンドを1つのALTERTABLEにまとめることはできないことに注意してください。
-- index operations -- change hash index bucket count ALTER TABLE dbo.TableName ALTER INDEX IX_Name REBUILD WITH (BUCKET_COUNT = 131072); GO -- add index ALTER TABLE dbo.TableName ADD INDEX IX_Name NONCLUSTERED (ColName); GO -- drop index ALTER TABLE dbo.TableName DROP INDEX IX_Name; GO -- add multiple indexes ALTER TABLE dbo.TableName ADD INDEX IX_Name NONCLUSTERED (ColName), INDEX IX_Name2 NONCLUSTERED (ColName2); GO -- Add a new column and an index ALTER TABLE dbo.TableName ADD Date DATETIME, INDEX IX_Name NONCLUSTERED (ColName); GO -- Drop a column ALTER TABLE dbo.TableName DROP COLUMN ColName; GO
テーブルタイプとテーブル変数
SQL Server 2016には、テーブル変数の定義時に使用できるメモリ最適化テーブルタイプを作成する機能があります。
CREATE TYPE TypeName AS TABLE ( Col1 SMALLINT NOT NULL, Col2 INT NOT NULL, Col3 INT NOT NULL, Col4 INT NOT NULL, INDEX IX_Col1 NONCLUSTERED HASH (Col1) WITH (BUCKET_COUNT = 131072), INDEX IX_Col1 NONCLUSTERED (Col2)) WITH (MEMORY_OPTIMIZED = ON); GO DECLARE @VariableName TypeName; GO
この変数はメモリにのみ保存されます。メモリ内で最適化されたテーブルとテーブルタイプは同じデータ構造を使用するため、データアクセスはディスクベースのテーブル変数と比較してより効率的になります。
詳細については、次のMSDNブログ投稿を参照してください。メモリ最適化を使用した一時テーブルとテーブル変数のパフォーマンスの向上
概要
インメモリOLTPは比較的若いテクノロジーであり、数百または数千の同時ユーザーをサポートする巨大で非常にビジーなOLTPシステムで動作するように設計されています。これはSQLServer2014で導入され、SQL Server 2016で進化しました。
同時に、このテクノロジには多くの制限と制限があります。
すべてのT-SQL機能とデータ型がメモリでサポートされているわけではありません-最適化されたテーブル。このようなテーブルには、8060バイトを超える行を含めることはできません。また、
ROW-OVERFLOWおよびLOBストレージもサポートしていません。テーブルが作成されると、(SQL Server 2014では)テーブルとインデックスを変更することはできません。
それにもかかわらず、インメモリOLTPの今後のバージョンでは制限が少なくなると予想されます!
また読む:
SQLServerのメモリ最適化テーブルでのインデックスの使用